2 minute read

현재 진행하고 있는 프로젝트중 요구사항을 구현하기 위해 스크린 캡처도구를 직접 구현해야하는 일이 있었고 이를 직접 구현하면서 Github에서 유사한 구현체들을 참고하면서 개발 하게 되었다. 그러나 이 과정에서 몇 가지 문제에 직면했는데 이 글에서는 문제 해결 과정을 공유하고자 한다.

깃 레포지토리 바로가기

문제 1: 해상도에 따른 지정 영역과 실제 영역의 오차

처음 구현한 스크린샷 도구는 해상도에 따라 지정한 영역과 실제 캡처된 영역에 오차가 발생하는 문제가 있었는데 고해상도의 화면에서만 해당 문제가 발생하였다. 이를 바탕으로 디스플레이의 배율 값을 불러와서 오차를 수정하면 될 것 같았다.

스택오버플로우 질문

스크린샷 도구의 해상도 문제를 해결하기 위해 스택오버플로우에 질문을 통해 다음과 같은 코멘트를 받았다:

You should read the QScreen, QPaintDevice (from which QWidget inherits) and the DPI related documentation.

코멘트에 따라 관련 문서를 읽기 시작했다.

DPI(Dots Per Inch) 이해하기

DPI는 인치당 점(Dot) 수를 의미하며, 디스플레이의 해상도를 측정하는 지표이다. 일반적으로 DPI가 높을수록 화면에 표시되는 이미지와 텍스트가 더 선명하고 자세하게 보인다. 과거에는 대부분의 모니터가 동일한 DPI를 가지고 있었지만(FHD, HD 등), 약 10년 전 애플의 레티나 디스플레이가 등장하면서 다양한 해상도(QHD, UHD 등)가 대중화 되었다.

고해상도와 배율 설정

고해상도 모니터에서는 더 많은 픽셀을 작은 공간에 배치하여 더 선명한 이미지를 제공한다. 하지만 이로 인해 기존 애플리케이션의 가시성이 좋지않는 문제가 발생할 수 있다. 이러한 문제를 해결하기 위해 운영체제는 배율 설정을 사용하여 UI 요소를 적절한 크기로 조정한다.

HiDPI 설정은 UI 요소만 특정 해상도에 맞게 스케일링할 뿐, 콘텐츠 자체는 원본 해상도를 유지한다. 예를 들어, 4K 27인치 화면을 200%로 스케일링해서 사용하는 경우 실제 해상도는 UHD이지만 UI 요소는 FHD처럼 표시된다. 즉, 콘텐츠의 내용은 4K 해상도를 유지하면서 UI 요소만 크기가 조정이 된다.

이로 인해 내가 작성한 프로그램에서 스크린샷 좌표를 지정할 때 실제 해상도와 스케일링된 배율 사이에 간극이 발생해서 오차가 발생한 것이다. HiDPI를 제대로 지원 하는 경우 프로그램은 Windows의 배율 설정 을 알고 표시하기 때문에 문제가 발생하지 않는다.

구현 과정

문서를 통해 학습한 내용을 바탕으로, QScreen 클래스의 screen.devicePixelRatio()를 사용하여 모니터의 배율 정보를 얻고, 이를 통해 사용자가 지정한 좌표 영역의 오차를 보정했다.

문제 2: 듀얼 모니터 지원 확장

해상도 문제를 해결한 후, 듀얼 모니터 환경에서도 스크린샷 도구가 정상적으로 동작하도록 기능을 확장했다. 이를 위해 각 모니터의 스크린 지오메트리를 읽어와서 각각의 모니터에 대해 스크린샷을 캡처하도록 수정했다.

구현 과정

  1. 모니터 개수 확인 및 설정:
    • self.screens() 메서드를 사용하여 현재 연결된 모든 모니터를 가져온다. 이를 통해 다중 모니터 환경에서도 각 모니터에 맞는 설정을 할 수 있다.
  2. 각 모니터 별 설정:
    • 각 모니터에 대해 반복문을 통해 지오메트리와 스케일링 팩터 정보를 가져온다.
    • screen.geometry()를 사용 하여 모니터의 해상도와 위치 정보를 얻는다.
    • screen.devicePixelRatio()를 사용하여 모니터의 배율 정보를 얻는다.
  3. 위젯 생성:
    • SnipWidget 클래스를 생성할 때, 각 모니터의 지오메트리와 스케일링 팩터를 인자로 전달하여 해당 모니터의 화면 크기에 맞는 위젯을 생성한다.
    • ImageGrab.grab() 함수에 all_screens=True 옵션을 추가하여 모든 모니터에서 스크린샷을 캡처할 수 있도록 했다.
    • 스크린샷 영역 지정시 스케일링 팩터로 오차를 보정한다.

결론

이렇게 두 가지 주요 문제를 해결하여 고해상도 및 듀얼 모니터 환경에서도 정확하게 동작하는 스크린샷 도구를 구현할 수 있었다. 이번 작업을 통해 공식 문서를 참고하며 개발하는 것이 얼마나 중요한지 다시 한번 느꼈고, 질문을 통해 현재 나의 부족한 점을 바로 파악할 수 있다는 것을 깨달았다.

어떤 모듈을 사용할지 결정하고, 참고한 구현체가 어떻게 동작하는지 소스 코드를 분석하며 개발하는 것이 중요하다는 점도 재확인 했다. 질문을 통해 필요한 문서를 읽어보라는 조언을 들었고, 이를 통해 DPI가 무엇인지 이해하고 문제 파악하여 문제 해결의 초석을 다질 수 있었다.

Leave a comment