오토핫키의 함수중 하나인 이미저서치를 사용하다보면, 여러 해상도, 색 비트 등과 같은 요소들로 인해 다른환경에서 이미지가 잘 검색이 되지않는 현상이 종종 발생합니다.
해당 라이브러리는 저장된 이미지를 예시로 보여주고, 사용자가 손쉽게 예시를 따라 이미지를 캡처해 이미지서치의 호환성을 개선하게 도와주는 라이브러리입니다.
해당 라이브러리의 함수는
1. GETIMAGE(ExampleImage, SaveImage:="")
: GETIMAGE(예시사진 경로 , [캡처사진 경로])
2. GETSQUAREIMAGE(ExampleImage, SaveImage:="", ImageW:="", ImageH:="")
: GETSQUAREIMAGE(예시사진 경로 , [캡처사진 경로], [영역 너비], [영역 높이])
이렇게 두가지이며, 사용환경에 따라서 인자를 다르게주어서 사용할 수 있습니다.
사용하시면서 질문이나 추가를 바라는 요소가 있다면 댓글 혹은 이메일로 남겨주세요.
본 라이브러리는 CC BY-SA 3.0 을 적용하고있습니다.
Example.zip
0.02MB
ImageSetting_Ext Lib.zip
0.02MB
- 예제
<html />;================================================================================== ; 파일명 : ImageSetting_Ext.ahk ; 설명 : 이미지서치 호환성 개선 라이브러리 ; 버전: v1.0 ; 라이센스: CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0/deed.ko) ; 설치방법: #Include ImageSetting_Ext.ahk ; 제작자: https://catlab.tistory.com/ (fty816@gmail.com) ;================================================================================== #Include Gdip_All.ahk ;================================================================================== ; 함수 설명 : ; 1. GETIMAGE(예시사진 경로 , [캡처사진 경로]) ; : 자유롭게 사각형을 그려 원하는 영역을 캡처합니다. ; : 캡처사진 경로가 지정되지 않을 경우 예시사진으로 즉시 교체합니다 ; ; 2. GETSQUAREIMAGE(예시사진 경로 , [캡처사진 경로], [영역 너비], [영역 높이]) ; : 지정된 영역을 캡처합니다. ; : 영역 너비와 높이를 지정하지 않을 경우 예시사진의 높낮이로 자동 설정됩니다 ;================================================================================== GETIMAGE(ExampleImage, SaveImage:="") { ImageSetting_Ext.Extraction.GETIMAGE(ExampleImage, SaveImage) } GETSQUAREIMAGE(ExampleImage, SaveImage:="", ImageW:="", ImageH:="") { ImageSetting_Ext.Extraction.GETSQUAREIMAGE(ExampleImage, SaveImage, ImageW, ImageH) } class ImageSetting_Ext { class Extraction extends ImageSetting_Ext.Funcs { GETIMAGE(ExampleImage, SaveImage:="") { this.__New() this.GetImage_Free(ExampleImage, SaveImage) this.__Delete() } GETSQUAREIMAGE(ExampleImage, SaveImage:="", ImageW:="", ImageH:="") { this.__New() this.GetImage_Square(ExampleImage, SaveImage, ImageW, ImageH) this.__Delete() } } class Funcs { __New() { this.EraseBgFunc := ObjBindMethod(this,"WM_ERASEBKGND") OnMessage(0x14, this.EraseBgFunc) this.GetLBMovFunc := ObjBindMethod(this,"WM_LBUTTONDOWN") OnMessage(0x201, this.GetLBMovFunc) Gui,Capture: New, -Caption +ToolWindow +LastFound -DPIScale WinSet, TransColor, Black this.Token := Gdip_StartUp() this.Pen := DllCall("CreatePen" , "int", PS_SOLID:=2 , "int", 1 , "uint", 0xff) } GetImage_Free(ExPic, SavePic:="") { CoordMode, Mouse, Screen this.Mode:=1 OriScreenBM := this.ShowScreen() this.ShowNotification(ExPic) this.SetCur("Cross.cur") KeyWait, LButton, D MouseGetPos, Start_X, Start_Y this.Ori_X := Start_X, this.Ori_Y := Start_Y RecFunc := this["Rec"].bind(this) SetTimer, % RecFunc, 10 KeyWait, LButton SetTimer, % RecFunc, Off MouseGetPos, End_X, End_Y Gui,Capture: Cancel this.DestroyScreen() this.DestroyNotification() this.RestoreCursor() if (End_X > Start_X AND End_Y > Start_Y) Capture_X:=Start_X, Capture_Y:=Start_Y else if (End_X < Start_X AND End_Y < Start_Y) Capture_X:=End_X, Capture_Y:=End_Y else if (End_X < Start_X AND End_Y > Start_Y) Capture_X:=End_X, Capture_Y:=Start_Y else if (End_X > Start_X AND End_Y < Start_Y) Capture_X:=Start_X, Capture_Y:=End_Y Capture_W := Abs(End_X-Start_X), Capture_H := Abs(End_Y-Start_Y) SavePic ? SavePic : SavePic := ExPic this.SaveImage(OriScreenBM, Capture_X, Capture_Y, Capture_W, Capture_H, SavePic) } GetImage_Square(ExPic, SavePic:="", Width:="", Height:="") { CoordMode, Mouse, Screen this.Mode:=0 OriScreenBM := this.ShowScreen() this.ShowNotification(ExPic) this.SetCur() if not (Width or Height) this.GetImageDimensions(ExPic, Width, Height) this.Width := Width, this.Height := Height MouseGetPos, Start_X, Start_Y this.Ori_X := Start_X, this.Ori_Y := Start_Y RecFunc := this["Rec"].bind(this) SetTimer, % RecFunc, 10 KeyWait, LButton, D SetTimer, % RecFunc, Off Gui,Capture: Cancel this.DestroyScreen() this.DestroyNotification() this.RestoreCursor() Capture_X := this.CurX, Capture_Y := this.CurY Capture_W := Width, Capture_H := Height SavePic ? SavePic : SavePic := ExPic this.SaveImage(OriScreenBM, Capture_X, Capture_Y, Capture_W, Capture_H, SavePic) } ShowScreen() { Gui,Screen: New, -Caption +ToolWindow +LastFound Gui, Add, Picture,x0 y0 hwndOriScreenHWND OriScreenBM := Gdip_BitmapFromScreen("0|0|" A_ScreenWidth "|" A_ScreenHeight) OriScreenHBM := Gdip_CreateHBITMAPFromBitmap(OriScreenBM) SetImage(OriScreenHWND, OriScreenHBM) Gui,Screen: Show,% "x0 y0 w" A_ScreenWidth "h" A_ScreenHeight return OriScreenBM } DestroyScreen() { Gui,Screen: Destroy } ShowNotification(Picture) { static NotiPic this.GetImageDimensions(Picture, PictureW, PictureH) this.NotiGui := {Text: {Cont: "다음과 같은 사진을 선택해주세요" , Color: "0x000000" , FontStyle: "Arial" , FontSize: "15" , FontBold: "Bold"} , BackgroundColor: "0xffffff" , MinPictureW: "150", MinPictureH: "150"} PictureW <= this.NotiGui.MinPictureW ? (GuiW := 187, TextW := 150, PictureW := 150, PictureH := -1) : (GuiW := 187 + (PictureW - this.NotiGui.MinPictureW), TextW := 150 + (PictureW - this.NotiGui.MinPictureW)) Gui, Noti: New, -Caption +ToolWindow +LastFound +Border +AlwaysOnTop Gui, Noti: Color, % this.NotiGui.BackgroundColor Gui, Noti: Font, % "c" this.NotiGui.Text.Color " s" this.NotiGui.Text.FontSize " w" this.NotiGui.Text.FontBold, % this.NotiGui.Text.FontStyle Gui, Noti: Add, Picture,% "vNotiPic Border w" PictureW " h" PictureH,% Picture Gui, Noti: Add, Text,% "w" TextW " Border Center", % this.NotiGui.Text.Cont Gui, Noti: Show,% "y" A_ScreenHeight * 0.01 } DestroyNotification() { Gui,Noti: Destroy } SaveImage(pBitmap, X, Y, W, H, FileDir) { pBitmap_Crop := Gdip_CloneBitmapArea(pBitmap, X, Y, W, H) Gdip_SaveBitmapToFile(pBitmap_Crop, FileDir) Gdip_DisposeImage(pBitmap), Gdip_DisposeImage(pBitmap_Crop) } GetImageDimensions(Picture, ByRef PictureW, ByRef PictureH) { PicBM := Gdip_CreateBitmapFromFile(Picture) Gdip_GetImageDimensions(PicBM ,PictureW ,PictureH) Gdip_DisposeImage(PicBM) } SetCur(Cursor:="") { SysCursors := ["32512","32513","32514","32515","32516","32640","32641","32642","32643","32644","32645","32646","32648","32649","32650","32651"] if FileExist(Cursor) CursorHandle := DllCall("LoadCursorFromFile", Str, A_ScriptDir "\" Cursor) else if (Cursor = "") { VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 ) BlankCur := DllCall("CreateCursor" ,Uint, 0, Int, 0, Int, 0, Int, 32, Int, 32, Uint, &AndMask, Uint, &XorMask) CursorHandle := DllCall("CopyImage", Uint, BlankCur, Uint, 0x2, Int, 0, Int, 0, Int, 0) } else return for i, v in SysCursors DllCall("SetSystemCursor", Uint, CursorHandle, Int, v) } RestoreCursor() { SPI_SETCURSORS := 0x57 DllCall("SystemParametersInfo", UInt,SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0) } Rec() { CoordMode, Mouse, Screen MouseGetPos, x2, y2 if !this.Mode { CurX := Ceil(x2 - this.Width * 0.5), CurY := Ceil(y2 - this.Height * 0.5) Gui,Capture: Show, % "NA X" CurX " Y" CurY " W" this.Width " H" this.Height Gui,Capture: +LastFound this.CurX := CurX, this.CurY := CurY } else { x1 := this.x1, y1 := this.y1 (x1 y1) = (x2 y2) ? return x2 < this.Ori_X ? (x1 := x2, x2 := this.Ori_X) : x1 := this.Ori_X y2 < this.Ori_Y ? (y1 := y2, y2 := this.Ori_Y) : y1 := this.Ori_Y this.x1 := x1, this.y1 := y1, this.x2 := x2, this.y2 := y2 Gui,Capture: Show, % "NA X" x1 " Y" y1 " W" x2-x1 " H" y2-y1 Gui,Capture: +LastFound } DllCall("RedrawWindow" , "uint", WinExist() , "uint", 0 , "uint", 0 , "uint", 5) return } __Delete() { this.Destroy() } Destroy() { OnMessage(0x200, this.EraseBgFunc, 0) OnMessage(0x201, this.GetLBMovFunc, 0) Gdip_Shutdown(this.Token) } WM_ERASEBKGND(wParam, lParam) { Critical 50 if A_Gui = Capture { blackBrush := DllCall("GetStockObject", "int", BLACK_BRUSH:=0x4) oldPen := DllCall("SelectObject", "uint", wParam, "uint", this.Pen) oldBrush := DllCall("SelectObject", "uint", wParam, "uint", blackBrush) Width := this.Mode ? this.x2-this.x1 : this.Width Height := this.Mode ? this.y2-this.y1 : this.Height DllCall("Rectangle", "uint", wParam, "int", 0, "int", 0, "int", Width, "int", Height) DllCall("SelectObject", "uint", wParam, "uint", oldPen) DllCall("SelectObject", "uint", wParam, "uint", oldBrush) return 1 } } WM_LBUTTONDOWN(wParam, lParam, msg, hwnd) { if A_Gui = Noti PostMessage, 0xA1, 2 } } }