이번 칼럼에서는 LDPlayer의 화면을 오토핫키와 GDI+ 라이브러리를 이용하여 비활성으로 이미지 찾기 방법에 대해서 알아 보겠습니다.

모바일 기기에서 24시간 동안 무거운 앱을 구동하게 되면 발열과 같은 문제가 많이 생깁니다. 이로 인해 LDPlayer와 같은 앱 플레이어를 PC에 설치해서 많이 사용합니다. 앱 플레이어를 통해 앱 사용 시 반복적인 부분이 발생 시 오토핫키 스크립트를 이용하여 자동화 할 필요가 있습니다.

오토핫키에서 기본적으로 제공하는 이미지서치(ImageSearch)는 모니터에 표시 되는 화면에서 찾고자 하는 이미지를 찾아 이미지가 위치하는 정보를 사용자에게 알려줍니다. 사용자는 이 정보들을 이용하여 상황을 판단하고, 다음에 수행할 이벤트를 정의할 수 있습니다. 하지만 기본 이미지서치는 탐색할 대상 윈도우가 다른 윈도우에 겹치지 않고 항상 최상위로 활성화 된 상태에서만 정상적으로 동작합니다.

쉽게 말해 이미지 서치가 수행중일때는 사용자가 다른 작업을 할 수가 없습니다. 사용자가 다른 작업을 하다 보면 자동화 시켜놓은 윈도우 프로그램이 비활성 상태가 되면서 다른 윈도우 프로그램에 의해 가려지게 됩니다.

이로 인해 기존에 작업 중이던 자동화 프로그램이 정상적으로 수행되지 않는 문제가 발생합니다. 이런 문제를 해결하기 위해 대상 윈도우가 비활성화 된 상태에서도 화면을 인식하는 방법이 필요합니다.

GDI

그래픽스 디바이스 인터페이스(Graphics Device Interface, GDI)의 정의는 아래와 같습니다. 짧게 요약하자면, MS Windows 환경에서 모니터 화면에 보여지는 모든 그래픽 요소들은 이 GDI를 통해서 보여준다고 생각하면 됩니다.

마이크로소프트 윈도(Microsoft Windows)에서 도형을 처리하고 이들을 출력 장치로 전송하는 응용 프로그램 인터페이스(API)이다. 모든 응용 프로그램은 화면 표시 또는 인쇄할 때 그래픽 디바이스 인터페이스(GDI)에 처리를 의뢰하면 GDI는 그 명령을 디스플레이 드라이버나 프린터 드라이버가 처리 가능한 형태로 변환하여 각각의 드라이버에 보냄으로써 화면 표시 또는 인쇄가 실행된다. -TTA정보통신용어사전

GDI+

GDI+는 GDI를 기반으로 새 기능이 추가 된 후속 버전의 응용 프로그램 인터페이스(API) 입니다. GDI에서는 핵심인 핸들(Handle)과 디바이스 컨텍스트(Device Context, DC)를 생성하고 관리하는것에 매우 신경써야 하지만, GDI+는 이런 문제를 해결하기 위해 객체지향적으로 모델을 변경했습니다. 따라서 GDI를 사용할 때처럼 핸들 및 디바이스 컨텍스트에 많은 신경을 쓸 필요가 없습니다.

오토핫키 Gdip 모듈

GDI+는 Win32 API 형태로 구성되어 있습니다. 오토핫키에서 Win32 API 형태의 GDI+를 사용하기 위해서는 매우 복잡한 방법을 통해서 사용할 수 있습니다. 하지만 매우 감사하게도 오토핫키 해외포럼에서 Gdip_All 모듈을 공유하고 있습니다. 이 모듈을 통해 GDI+ API를 오토핫키에서도 매우 쉽게 사용할 수 있게 되었습니다.

이 모듈을 이용하여 대상 윈도우 프로그램의 화면 정보를 우리가 만들 프로그램의 변수(메모리)로 저장할 수 있습니다. 물론, 대상 윈도우 프로그램이 비활성화 된 상태에서도 화면 정보를 가져올 수 있습니다. (단, 최소화 모드에서는 불가능)

;###################
; 제공되는 함수 목록
;###################

 UpdateLayeredWindow(hwnd, hdc, x=, y=, w=, h=, Alpha=255)
 BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster=)
 StretchBlt(dDC, dx, dy, dw, dh, sDC, sx, sy, sw, sh, Raster=)
 SetImage(hwnd, hBitmap)
 Gdip_BitmapFromScreen(Screen=0, Raster=)
 CreateRectF(ByRef RectF, x, y, w, h)
 CreateSizeF(ByRef SizeF, w, h)
 CreateDIBSection

오토핫키 Gdip_ImageSearch 모듈

Gdip 모듈을 이용하여 대상 프로그램의 화면 정보를 가지고 왔습니다. 이제 이 화면 정보에서 우리가 찾고자 하는 이미지를 찾아야 합니다. 오토핫키 해외포럼에서는 GDI+를 이용해서 이미지서치 할 수 있도록 Gdip_ImageSearch 모듈을 공유하고 있습니다.

아래 소스코드는 Gdip_ImageSearch 함수를 사용하기 위해 입력해야 하는 인자(Parameter) 입니다. 대상 윈도우의 전체화면 정보는 pBitmapHaystack이며, 찾을 이미지 정보는 pBitmapNeedle에 저장하여 인자로 입력해야 합니다. 두 변수는 모두 데이터 타입이 비트맵(BITMAP)으로 구성되어야 합니다.

Gdip_ImageSearch(   pBitmapHaystack,            ; 대상 이미지
                    pBitmapNeedle,              ; 탐색 이미지
                    ByRef OutputList=,        ; 탐색된 좌표 리스트
                    OuterX1=0,                  ; 시작탐색범위(X1)
                    OuterY1=0,                  ; 시작탐색범위(Y1)
                    OuterX2=0,                  ; 종료탐색범위(X2)
                    OuterY2=0,                  ; 종료탐색범위(Y2)
                    Variation=0,                ; 오차율(0~255)
                    Trans=,                   ; 투명화색상
                    SearchDirection=1,          ; 탐색방향
                    Instances=1,                ; 탐색 최대 갯수
                    LineDelim=`n,             ; OutputList에 저장되는 라인 구분자
                    CoordDelim=,)             ; OutputList에 저장되는 좌표 구분자

개선 함수

오토핫키에서 제공하는 이미지서치(ImageSearch) 함수에 익숙한 사용자라면 위 GDI+ 관련 함수들을 사용하기가 매우 어렵습니다. Gdip_All.ahk와 Gdip_ImageSearch.ahk를 활용하여 사용하기 쉽도록 새로운 함수를 만들었습니다.

;TaskAutoLab 이미지서치 함수
TAL_ImageSearch(WindowTitle,            ;WindowTitle : 윈도우명
                byref OutputVarX=0,     ;OutputVarX : 결과 X좌표
                byref OutputVarY=0,     ;OutputVarY : 결과 Y좌표
                X1=0,                   ;X1 : 시작 X좌표
                Y1=0,                   ;Y1 : 시작 Y좌표
                X2=0,                   ;X2 : 종료 X좌표
                Y2=0,                   ;Y2 : 종료 Y좌표
                Variation=30,           ;Variation : 오차율(0~255)
                Direct=1,               ;Direct : 탐색방향
                ImageFile,              ;Image : 이미지파일
                byref Error=)           ;Error : 오류 메시지

사용 예제


본 칼럼 내용에 대해 문의 하실 사항이나 필요하신 칼럼 주제가 있으시면 언제든지 댓글로 알려주세요.