동일 이미지를 모두 찾는 멀티 이미지서치 예제 스크립트 입니다.

 

테스트 실행 GIF 이미지

 

[테스트 스크립트]

Test_멀티서치.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

멀티서치_테스트.zip
0.00MB

#SingleInstance Force

Hotkey, ESC, ExitApp

검색테이블 := "검색테이블.png"
검색이미지 := "검색이미지.png"

MsgBox, 이미지서치 테스트를 위해 '%검색테이블%' 이미지를`n그림판으로 열어야 합니다.
Run, mspaint.exe "%검색테이블%",,, pid
sleep, 100

if pid
{
  WinWait, ahk_pid %pid%,, 5
  if foundWin := WinExist("ahk_pid " pid)
    sleep, 300
}

if foundWin
{
  ;열려있는 그림판 윈도우에서 이미지 멀티서치 (반환 좌표는 찾은 이미지의 센터 좌표)
  ImageSearch, sx,sy, 0,0,800,800, *All *ResultCenter %검색이미지%, result
  if ErrorLevel {
    MsgBox, 그림판 윈도우에서 '%검색이미지%' 이미지를 찾는데 실패하였습니다.
    ExitApp
  }
  
  ;찾은 좌표 출력
  loop % result.count
    text .= A_Index " : " result[A_Index].x "," result[A_Index].y "`n"
  MsgBox % "그림판 윈도우에서 '" 검색이미지 "' 이미지를 " result.count "개 찾았습니다.`n`n" text
  
  ;그림판 윈도우에서 단축키를 이용해 채우기 툴 선택
  WinActivate, % "ahk_pid " pid
  Send, {Alt Down}h{Alt Up}
  sleep, 100
  Send, k
  
  ;찾은 좌표 마우스로 추적
  loop % result.count
  {
    MouseClick, Left, % result[A_Index].x, % result[A_Index].y
    sleep, 500
  }
  MsgBox, 멀티서치 테스트 완료
}
else
  MsgBox, %검색테이블% 이미지를 그림판으로 여는데 실패했습니다.
ExitApp

ExitApp:
ExitApp

 

Posted by 와이로

#UseFileInstallZipMode 지시어를 스크립트에 추가 할 시 FileInstall 명령어의 파라미터로 등록된 파일들이 zip 파일로 모두 합쳐진 후 컴파일된 exe 파일의 리소스에 등록됩니다.

 

#UseFileInstallZipMode [, zipResouceName]

 

왼쪽이 기존의 리소스 등록방식이고 오른쪽이 ZIP 파일 압축을 이용한 리소스 등록방식입니다.

사용 지시어 : #UseFileInstallZipMode, FileInstall

 

Posted by 와이로

텔레그램으로 메시지나 이미지를 전송하기 위한 스크립트 입니다.


(주의) 텔레그램에서 패치가 된건지 모르겠지만 현재 봇이 관리자인 채널로만 메시지 전송이 되고 개인 챗 아이디를 대상으로는 전송이 되지 않습니다.(2019-04-19)


전송결과확인 : http://t.me/telebottester



[테스트 스크립트]

Test_텔레그램이미지전송.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

Test_텔레그램이미지전송.zip


1. 텔레그램 메시지 전송용 봇 토큰은 메신저에서 'BotFather' 봇을 찾아 들어간 후 /newbot 명령을 입력해 생성할 수 있습니다.

 

2. 챗 아이디는 본인의 챗 아이디를 사용하거나 '@공개채널명'을 사용할 수 있습니다. 공개채널 사용시에는 1번 토큰 생성파트에서 생성한 봇을 해당 채널의 관리자로 임명한 상태여야 합니다.

 

   - 본인 챗 아이디 알아내는 법 : 메신저에서 'GetIDs Bot' 봇을 찾아 들어간 후

   /my_id 명령을 입력해 알아낼 수 있습니다.

 

   - 오픈채널에서 봇을 관리자로 초대 하는 법 : 오픈채널안에서 채널제목 터치 후

   설정 아이콘을 눌러 '채널 관리' 창으로 진입 후 관리자 메뉴의 '관리자 추가'를 눌러

   봇 이름을 찾아 초대 할 수 있습니다.

 

#SingleInstance Force

#include telegram.ahk


token := "830884232:AAFlwrJ5LSGM6pLBNjmMQtMj3ISboaDcVtg"

chat_id := "@telebottester"


;3. 메시지 전송

result := SendTelegramMessage(token, chat_id, "메시지 전송테스트 입니다.", "")

MsgBox % "텔레그램 메시지 " (result? "전송성공":"전송실패")


;4. 이미지 파일 전송

imageFile := "이미지.png"

result := SendTelegramMessage(token, chat_id, "전송이미지설명 파일전송", imageFile)

MsgBox % "텔레그램 이미지파일 " (result? "전송성공":"전송실패")


;5. 이미지 캡쳐 후 전송

ImageGet, hBitmap, 0,0,200,200,, *WH ;윈도우 스샷

result := SendTelegramMessage(token, chat_id, "전송이미지설명 캡쳐전송", hBitmap)

DllCall("DeleteObject", "UPtr",hBitmap)

MsgBox % "텔레그램 캡쳐이미지 " (result? "전송성공":"전송실패")


ExitApp



Posted by 와이로

특정 체크박스나 라디오버튼의 하위 콘트롤로 등록된 모든 콘트롤들을 일괄적으로 활성화시키거나 비활성 시키는 좀더 편한 방법을 찾다가 만든 유틸리티 입니다.



1. #include CGuiVLabelLink.ahk  헬퍼 클래스를 인클루드 시킵니다.


2. Gui, Add, Checkbox, vCheckA1 gCheckA1, 체크박스  처럼 v라벨과 g라벨의 이름이 동일해야 합니다.


3. GetGuiChildList(label, conValue) 사용자 함수를 생성합니다. 

- root 는 v라벨의 연결 상태를 반영한 오브젝트이며 노드는 체크박스나 라디오 박스만 사용해야 합니다.

- _CheckA3 이나 _CheckB3 처럼 라벨 이름 앞에 '_' 기호를 붙인 경우 하위 콘트롤의 활성화 동작을 역으로 수행합니다.

- CheckA2:{"":"show_hide"} 나 _CheckA3:{"":"show_hide"} 처럼 특정 노드에 'show_hide' 옵션을 넣을시 하위 콘트롤의 활성화 동작이 show/hide 동작을 수행합니다.


GetGuiChildList(label, conValue)

{

  static cls

  if !cls {

    ;주황색 부분을 현재 GUI상 콘트롤의 v라벨 연결 상태에 맞게 수정해야 합니다.

    root := {Check:{CheckA1:{}, CheckB1:{}}}

    root.Check.CheckA1 := {CheckA2:{"":"show_hide", _CheckA3:{"":"show_hide", CheckA4:{CheckA5:0}}}}

    root.Check.CheckB1 := {CheckB2:{_CheckB3:{CheckB4:{CheckB5:0}, CheckC1:{CheckC2:0}}}}

    cls := new CGuiVLabelLink(root)

  }

  return cls.GetGuiChildList(label, conValue)

}


4. g라벨 수행부에 아래 코드를 넣어주면 해당 콘트롤을 체크하거나 해제할때 하위 콘트롤을 활성/비활성 시킬 수 있습니다.

  GuiControlGet, conValue,, % A_ThisLabel

  for k,v in GetGuiChildList(A_ThisLabel, conValue)

    GuiControl, % v.cmd, % v.name



[테스트 스크립트]


Test_GUI콘트롤_일괄비활성.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

Test_GUI콘트롤_일괄비활성.zip


1. Test_GUI콘트롤_일괄비활성1.ahk


#SingleInstance, force

#include CGuiVLabelLink.ahk


;1. v라벨과 g라벨의 이름은 동일해야 합니다.

Gui, new

Gui, Add, Checkbox, xm     vCheck   gCheck  , 체크

Gui, Add, Checkbox, xm     vCheckA1 gCheckA1, 체크A1

Gui, Add, Checkbox, xp+70  vCheckA2 gCheckA2, 체크A2

Gui, Add, Checkbox, xp+70  vCheckA3 gCheckA3, 체크A3

Gui, Add, Checkbox, xp+70  vCheckA4 gCheckA4, 체크A4

Gui, Add, Checkbox, xp+70  vCheckA5 gCheckA5, 체크A5

Gui, Add, Checkbox, xm     vCheckB1 gCheckB1, 체크B1

Gui, Add, Checkbox, xp+70  vCheckB2 gCheckB2, 체크B2

Gui, Add, Checkbox, xp+70  vCheckB3 gCheckB3, 체크B3

Gui, Add, Checkbox, xp+70  vCheckB4 gCheckB4, 체크B4

Gui, Add, Checkbox, xp+70  vCheckB5 gCheckB5, 체크B5

Gui, Add, Checkbox, xm+140 vCheckC1 gCheckC1, 체크C1

Gui, Add, Checkbox, xm+140 vCheckC2 gCheckC2, 체크C2

Gui, Show


;3. GUI 생성 후 초기화 작업이며, 체크박스나 라디오버튼의 값에 따라 하위 콘트롤을 enable/disable 또는 show/hide 시킵니다.

  for k,v in GetGuiChildList("","")

    GuiControl, % v.cmd, % v.name

return


;2. v라벨 연결 상태를 반영한 오브젝트이며 노드는 체크박스나 라디오 박스만 사용해야 합니다.

;ㄴ _CheckA3 이나 _CheckB3 처럼 라벨 이름 앞에 '_' 기호를 붙인 경우 하위 콘트롤의 활성화 동작을 역으로 수행합니다.

;ㄴ CheckA2:{"":"show_hide"} 이나 _CheckA3:{"":"show_hide"} 처럼 특정 노드에 'show_hide' 옵션을 넣을시 하위 콘트롤의 활성화 동작이 show/hide 동작을 수행합니다.

GetGuiChildList(label, conValue)

{

  static cls

  if !cls {

    root := {Check:{CheckA1:{}, CheckB1:{}}}

    root.Check.CheckA1 := {CheckA2:{"":"show_hide", _CheckA3:{"":"show_hide", CheckA4:{CheckA5:0}}}}

    root.Check.CheckB1 := {CheckB2:{_CheckB3:{CheckB4:{CheckB5:0}, CheckC1:{CheckC2:0}}}}

    cls := new CGuiVLabelLink(root)

  }

  return cls.GetGuiChildList(label, conValue)

}


Check:

CheckA1:

CheckA2:

CheckA3:

CheckA4:

CheckA5:

CheckB1:

CheckB2:

CheckB3:

CheckB4:

CheckB5:

CheckC1:

CheckC2:

 

  GuiControlGet, conValue,, % A_ThisLabel

  for k,v in GetGuiChildList(A_ThisLabel, conValue)

    GuiControl, % v.cmd, % v.name

return



2. Test_GUI콘트롤_일괄비활성2.ahk


#SingleInstance, force
#include CGuiVLabelLink.ahk


;1. v라벨과 g라벨의 이름은 동일해야 합니다.
Gui, new
Gui, Add, Checkbox, xm         vCheck  gCheck   , 체크

Gui, Add, Checkbox, xp+70     vCheck1 gCheck1 , 선택1
Gui, Add, Text        , xp+70    vText1  gText1      , 에디트1
Gui, Add, Edit        , x+3 yp-3 vEdit1  gEdit1
Gui, Add, Text        , xm+140  vText2  gText2      , 에디트2
Gui, Add, Edit        , x+3 yp-3 vEdit2  gEdit2

Gui, Add, Checkbox, xm+70    vCheck2 gCheck2 , 선택2
Gui, Add, Text        , xp+70    vText3  gText3     , 에디트3
Gui, Add, Edit        , x+3 yp-3 vEdit3  gEdit3
Gui, Add, Text        , xm+140  vText4  gText4    , 에디트4
Gui, Add, Edit        , x+3 yp-3 vEdit4  gEdit4
Gui, Show

;3. GUI 생성 후 초기화 작업이며, 체크박스나 라디오버튼의 값에 따라 하위 콘트롤을 enable/disable 또는 show/hide 시킵니다.
  for k,v in GetGuiChildList("","")
    GuiControl, % v.cmd, % v.name
return

;2. v라벨 연결 상태를 반영한 오브젝트이며 노드는 체크박스나 라디오 박스만 사용해야 합니다.
;ㄴ _Check2 처럼 라벨 이름 앞에 '_' 기호를 붙일경우 하위 콘트롤의 활성화 동작을 역으로 수행합니다.
;ㄴ _Check2:{"":"show_hide"} 처럼 특정 노드에 'show_hide' 옵션을 넣을시 하위 콘트롤의 활성화 동작이 show/hide 동작을 수행합니다.
GetGuiChildList(label, conValue)
{
  static cls
  if !cls {
    root := {Check:{Check1:{}, _Check2:{}}}
    root.Check.Check1 := {Text1:0, Edit1:0, Text2:0, Edit2:0}
    root.Check._Check2 := {Text3:0, Edit3:0, Text4:0, Edit4:0, "":"show_hide"}
    cls := new CGuiVLabelLink(root)
  }
  return cls.GetGuiChildList(label, conValue)
}

Check:

Check1:
Text1:
Edit1:
Text2:
Edit2:

Check2:
Text3:
Edit3:
Text4:
Edit4:

  GuiControlGet, conValue,, % A_ThisLabel
  for k,v in GetGuiChildList(A_ThisLabel, conValue)
    GuiControl, % v.cmd, % v.name
return




Posted by 와이로

주로 비활성 캡쳐시 PrintWindow() API 를 이용하는데 윈도우7 이하의 버전에서는 OpenGL 캡쳐가 불가능한 문제가 발생하여 DLL 후킹을 이용한 캡쳐를 만들어 보았습니다. 캡쳐용 DLL은 OBS studio에서 가져와 수정해서 사용했습니다.


Test_MomoCapture.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

Momo_ModuleCapture.zip


아래는 타이틀이 LDPlayer-1 인 앱플레이어를 대상으로 한 캡쳐테스트입니다.


Posted by 와이로

최종수정 : 2019-08-31 디펜더에서 바이러스로 오진되는 현상 수정



디컴파일로부터 소스보호를 위한 오토핫키 암호화 컴파일러를 임시 공유합니다.

특정 게임의 가드나 NGS를 우회하는 기능은 고려하지 않았으므로 해당 기능에 대한 문의는 받지 않습니다.



설치 방법


AHK+ 암호화 컴파일러 설치프로그램으로 원하는 타입의 오토핫키를 설치할 수 있으며 기존 오토핫키가 설치되어 있을 경우 기본설치 경로가 해당 위치로 지정됩니다.

설치에 실패하는 경우 AutoHotkey.exe 로 실행된 프로세스를 모두 종료하거나 설치폴더를 C:\AutoHotkey 로 바꾼 후 재시도 해보세요.


오핫플러스설치.zip



디컴파일 방해 방식


암호화된 스크립트를 한번에 복호화 하지 않고 요소별로 분해하여 각기 다른 위치에서 복호화 하도록 만들어 디컴파일을 방해하도록 하였습니다. 단 올리디버거 같은 디버깅툴을 이용해 일부 메모리 값을 바꾸는 크래킹은 막을수 없습니다.




개별 스크립트 암호화


알고리즘 등의 노하우를 공개하고 싶지않은 스크립트를 공유해야 할때 ahk 파일을 컴파일하지 않고 스크립트 상태로 암호화 해서 공유할 수 있습니다. 암호화된 스크립트는 오토핫키플러스(AHK+)가 설치된 PC에서 사용 가능하며 컴파일도 가능합니다.


스크립트 암호화는 파일탐색기의 ahk 파일 우클릭시 팝업되는 'Obfuscate Script' 메뉴 또는 컴파일러 실행 후 '암호화출력모드' 탭에서 진행 할 수 있습니다.




스크립트 암호화시 메인스크립트가 위치하는 폴더 또는 하위폴더에 위치한 스크립트 중 #include 로 포함된 스크립트만 암호화 후 출력폴더에 저장합니다. 인클루드 하지않고 라이브러리 폴더에서 자동사용된 스크립트는 저장목록에서 제외됩니다.


윈도스파이_암호화테스트.zip




문의사항은 아래 카톡방을 두드리세요. (확인이 늦을 수 있으므로 문의내용을 미리 적어주세요.)

https://open.kakao.com/o/slwX64Y




Posted by 와이로

ADB shell screencap 명령으로 디바이스 내부에 별도이미지파일 저장없이 바로 HBITMAP 이미지로 가져오는 방법 (32비트 오토핫키용)


테스트 에뮬레이터 - [MOMO]앱플레이어




;--------------------------------------------------------------------

#SingleInstance Force

#include Gdip.ahk  ;https://autohotkey.com/board/topic/29449-gdi-standard-library-145-by-tic/


;MCode Func

AdjustScreencapData := MCode("2,x86:VVdWU4tsJBSLRCQYjXQF/zn1d1ONfv6NTQGJ6usRZpCJyIPCAYhZ/4PBATnydyI51w+2GnbqgPsNdeWAegENdd8PtloCgPsKdBa7DQAAAOvPKehbXl9dw5CNtCYAAAAAiciDwgPrvjHA6+iQkJCQkA==")

ScreencapToDIB := MCode("2,x86:VVdWU4PsDItEJCiLdCQkhcB+fY0EtQAAAACLVCQsxwQkAAAAAMdEJAQAAAAA99iJRCQIi0QkKIPoAQ+vxo08goX2fjuLRCQgi0wkBDHbjSyIi0SdDInCweoQD7bKicIlAP8AAMHiEIHiAAD/AAnKCdCJBJ+DwwE53nXWAXQkBIMEJAEDfCQIiwQkOUQkKHWwg8QMW15fXcOQkJCQkJCQkA==")



^\::ExitApp


F1::

  RegRead, MomoDir, HKCU, Software\NOXGAMES\MOMO, InstallDir

  adb_path = %MomoDir%adb.exe

  Runwait, "%adb_path%" devices


  sCmd = "%adb_path%" -s "127.0.0.1:5555" shell screencap  ;127.0.0.1:5555 = MoMo 기본 앱플레이어

  if hBitmap := ADBScreenCapStdOutToHBitmap( sCmd )

  {

    SaveHBITMAPToFile(hBitmap, "_testImage.bmp")

    DllCall("DeleteObject", Ptr,hBitmap)

  }

  MsgBox, % hBitmap? "screen cap 이미지 추출성공":"실패"

return


;--------------------------------------------------------------------

;https://autohotkey.com/board/topic/96903-simplified-versions-of-seans-stdouttovar/

ADBScreenCapStdOutToHBitmap( sCmd ) {

  global AdjustScreencapData, ScreencapToDIB


  DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 )

  DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 )


  VarSetCapacity( STARTUPINFO, 68,  0 )      ; STARTUPINFO          ;  http://goo.gl/fZf24

  NumPut( 68,         STARTUPINFO,  0 )      ; cbSize

  NumPut( 0x100,      STARTUPINFO, 44 )      ; dwFlags    =>  STARTF_USESTDHANDLES = 0x100 

  NumPut( hPipeWrite, STARTUPINFO, 60 )      ; hStdOutput

  NumPut( hPipeWrite, STARTUPINFO, 64 )      ; hStdError


  VarSetCapacity( PROCESS_INFORMATION, 16 )  ; PROCESS_INFORMATION  ;  http://goo.gl/b9BaI      


  If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ;  http://goo.gl/USC5a

              , UInt,1, UInt,0x08000000, UInt,0, UInt,0

              , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) 

    Return "" 

    , DllCall( "CloseHandle", UInt,hPipeWrite ) 

    , DllCall( "CloseHandle", UInt,hPipeRead )

    , DllCall( "SetLastError", Int,-1 )


  hProcess := NumGet( PROCESS_INFORMATION, 0 )                 

  hThread  := NumGet( PROCESS_INFORMATION, 4 )                      


  DllCall( "CloseHandle", UInt,hPipeWrite )


  block := {}, blockIndex := 0, allSize := 0, nPipeAvail := 4096

  loop

  {

    ++blockIndex

    block[blockIndex] := {data:"", size:0, addr:0}

    ObjSetCapacity(block[blockIndex], "data", nPipeAvail)

    block[blockIndex].addr := ObjGetAddress(block[blockIndex], "data")

    

    nSz := 0

    if !DllCall( "ReadFile", UInt,hPipeRead, UInt,block[blockIndex].addr, UInt,nPipeAvail, UIntP,nSz, UInt,0 )

      break

    block[blockIndex].size := nSz, allSize += nSz

  }


  DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode )

  DllCall( "CloseHandle", UInt,hProcess  )

  DllCall( "CloseHandle", UInt,hThread   )

  DllCall( "CloseHandle", UInt,hPipeRead )


  if allSize

  {

    VarSetCapacity( bin, allSize, 0 ), tar := &bin

    for k,v in block

      if v.size

        DllCall("RtlMoveMemory", "UPTR",tar, "UPTR",v.addr, "UInt",v.size), tar += v.size

    allSize := DllCall(AdjustScreencapData, "UPTR",&bin, "UInt",allSize, "cdecl")

    width  := NumGet(&bin, 0, "uint"), height := NumGet(&bin, 4, "uint")

    hBM := CreateDIBSection(width, height,"",32, ppvBits)  

    DllCall(ScreencapToDIB, "UPtr",&bin, "UInt",width, "UInt",height, "UPtr",ppvBits, "cdecl")

    return hBM

  }

  

}

 

;--------------------------------------------------------------------

MCode(mcode) {

static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"

if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))

return

if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))

return

p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")

if (c="x64")

DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)

if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))

return p

DllCall("GlobalFree", "ptr", p)

    return

}


SaveHBITMAPToFile(hBitmap, sFile)

{

  VarSetCapacity(DIBSECTION, A_PtrSize=8? 104:84, 0)

  NumPut(40, DIBSECTION, A_PtrSize=8? 32:24,"UInt") ;dsBmih.biSize

  DllCall("GetObject", "UPTR", hBitmap, "int", A_PtrSize=8? 104:84, "UPTR", &DIBSECTION)

  hFile:= DllCall("CreateFile", "UPTR", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)

  DllCall("WriteFile", "UPTR", hFile, "int64P", 0x4D42|14+40+(biSizeImage:=NumGet(DIBSECTION, A_PtrSize=8? 52:44, "UInt"))<<16, "Uint", 6, "UintP", 0, "Uint", 0)

  DllCall("WriteFile", "UPTR", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)

  DllCall("WriteFile", "UPTR", hFile, "UPTR", &DIBSECTION + (A_PtrSize=8? 32:24), "Uint", 40, "UintP", 0, "Uint", 0)

  DllCall("WriteFile", "UPTR", hFile, "Uint", NumGet(DIBSECTION, A_PtrSize=8? 24:20, "UPtr"), "Uint", biSizeImage, "UintP", 0, "Uint", 0)

  DllCall("CloseHandle", "UPTR", hFile)

}







Posted by 와이로

 

스테가노그래피(Steganography) 기법으로 이미지에 문자열 숨기기

 

스테가노그래피란? https://bpsecblog.wordpress.com/2016/08/21/amalmot_4/

 

 

 

Test_스테가노.zip

 

                    1.BMP                                          2.BMP

 

                 3.BMP

 

 

 

1.BMP 와 2.BMP 는 같은 그림처럼 보이지만 2.BMP에는 이미지를 설명할수 있는 문자열이 특수한 형태로 숨겨서 저장되어 있으며 테스트파일을 실행 후 F1을 눌러보면 숨겨진 스테가노그래피 문자열을 확인 할 수 있습니다.

 

3.BMP는 스테가노그래피가 적용된 영역을 시각적으로 표시하기 위해 1.BMP 이미지와 2.BMP 이미지를 비교한 결과를 출력해본 것입니다. (픽셀값이 1비트라도 다른경우 흰색으로 표시)

 

 


< AHK+ 소스코드 >

 

;-------------------------------------------------------------------
;
;이 스크립트는 기존 오토핫키에서는 동작하지 않습니다.
;
;스테가노그래피 기법을 이용하면 이미지에 대한 간단한 정보를 별도
;파일에 기록하지 않고 이미지 자체에 바로 저장할수 있겠다 싶어서
;재미로 추가해 본 기능입니다.
;
;-------------------------------------------------------------------


#SingleInstance Force
srcFile = 1.bmp  ;원본 이미지
tarFile = 2.bmp  ;스테가노그래피 형태의 문자열을 저장할 이미지
txtFile = %tarFile%_에서추출한문자열.txt  ;추출한 스테가노그래피 문자열 저장용 텍스트 파일
MsgBox, 클립보드에 저장된 문자열을 스테가노그래피 형태로`n%srcFile% 이미지에 적용해 %tarFile% 파일로 저장합니다.`n`nF1 : %tarFile% 에 적용된 스테가노그래피 문자열 추출`nF2 : 스테가노그래피 적용(문자열 + %srcFile% -> %tarFile%)`n`nESC 키를 누르면 테스트가 종료됩니다.

 

;이미지에서 스테가노그래피 형태로 저장된 문자열을 추출한다.
F1::
  ImageGet,,,,,, tarFile, *SteganoRead, result
  if ErrorLevel
  {
    MsgBox, "%tarFile%" 이미지에 적용된 스테가노그래피 문자열이 없습니다.
    return
  }
  FileDelete, % txtFile
  FileAppend, % result.stegano, % txtFile
  MsgBox % "< """ tarFile """ 이미지에 숨겨진 문자열 >`n`n" result.stegano
return

 

;클립보드에 있는 문자열을 스테가노그래피 형태로 이미지에 저장한다.
F2::
  str = %Clipboard%
  ImageGet, hBitmap,,,,, srcFile, *SteganoWrite%str%
  if hBitmap
  {
    SaveHBitmapToFile(hBitmap, tarFile), DllCall("DeleteObject", "Ptr",hBitmap)
    MsgBox, 스테가노그래피 적용 성공`n`n"%tarFile%"에 저장 되었습니다.
  }
  else
    MsgBox, 스테가노그래피 적용 실패
return

 

;테스트 종료
Esc::
  MsgBox, 스테가노그래피 테스트를 종료합니다.
ExitApp


;----------------------------------------------------------------------------------
SaveHBITMAPToFile(hBitmap, sFile)
{
  VarSetCapacity(DIBSECTION, A_PtrSize=8? 104:84, 0)
  NumPut(40, DIBSECTION, A_PtrSize=8? 32:24,"UInt") ;dsBmih.biSize
  DllCall("GetObject", "UPTR", hBitmap, "int", A_PtrSize=8? 104:84, "UPTR", &DIBSECTION)
  hFile:= DllCall("CreateFile", "UPTR", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "int64P", 0x4D42|14+40+(biSizeImage:=NumGet(DIBSECTION, A_PtrSize=8? 52:44, "UInt"))<<16, "Uint", 6, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "UPTR", &DIBSECTION + (A_PtrSize=8? 32:24), "Uint", 40, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "Uint", NumGet(DIBSECTION, A_PtrSize=8? 24:20, "UPtr"), "Uint", biSizeImage, "UintP", 0, "Uint", 0)
  DllCall("CloseHandle", "UPTR", hFile)
}

Posted by 와이로

모바일게임 히트같은 경우 녹스와 블루스택에서 색상이 다르게 나옵니다. 이 때문에 한쪽에서 추출한 이미지를 다른쪽에서 활용 할 수가 없더군요.

 

1. 녹스 이미지

 

2. 블루스택 이미지

 

 

해결 방법을 찾던 중... 색상을 회색톤으로 바꾸니 녹스에서 추출한 이미지로 블루스택상의 이미지에서 이미지서치에 성공을 했습니다. 대부분 공차값 50 내에서 찾아지더군요.

 

3. 녹스이미지를 회색톤으로 바꾼 것

 

4. 블루스택 이미지를 회색톤으로 바꾼 것

 

 

이렇게 테스트한 결과를 가지고 ImageSearch 명령에서 쉽게 사용할 수 있도록 *FilterGray 옵션으로 추가 했습니다.

 


 

아래 스크립트는 녹스에서 추출한 '우편함' 이미지를 사용해 블루스택상의 이미지에서 검색하는 스크립트입니다.

 

 

 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

ImageSearch_FilterGray옵션.zip

 

 

<스크립트>

 

imgFind = image검색.bmp
img녹스 = image녹스.bmp
img블택 = image블택.bmp

공차 = 30

 

text := "녹스 스샷에서 추출한 이미지로 이미지서치 한 결과`n`n"
text .= "`n[*FilterGray 옵션 사용 전]`n"
ImageSearch, sx,sy, 0,0,0,0, *TargetFile<%img녹스%> *%공차% %imgFind%
if !ErrorLevel
  text .= "녹스 스샷에서 검색성공 : " sx "," sy "`n"
ImageSearch, sx,sy, 0,0,0,0, *TargetFile<%img블택%> *%공차% %imgFind%
if !ErrorLevel
  text .= "블택 스샷에서 검색성공 : " sx "," sy "`n"

 

text .= "`n[*FilterGray 옵션 사용 후]`n"
ImageSearch, sx,sy, 0,0,0,0, *FilterGray *TargetFile<%img녹스%> *%공차% %imgFind%
if !ErrorLevel
  text .= "녹스 스샷에서 검색성공 : " sx "," sy "`n"
ImageSearch, sx,sy, 0,0,0,0, *FilterGray *TargetFile<%img블택%> *%공차% %imgFind%
if !ErrorLevel
  text .= "블택 스샷에서 검색성공 : " sx "," sy "`n"

 

MsgBox % text

 

 

 

 

 

 

Posted by 와이로

오토핫키 ImageFilter 명령어로 이미지에 그레이필터 적용

 

1. 원본 이미지

 

2. 절반만 그레이필터 적용

 

 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

Gray필터테스트.zip

 

 

<스크립트>


imgFile = 1.bmp

ImageGet, hBitmap,,,,, imgFile  ;이미지파일 로드

ImageFilter, Gray, hBitmap, hBitmap, 0,0,800,900  ;그레이필터 적용

SaveHBITMAPToFile(hBitmap, "2.bmp")

DllCall("DeleteObject", "Ptr",hBitmap)



 

 

 

 

 

 

 

Posted by 와이로

이미지에 필터효과를 적용하기 위해 추가한 명령어입니다.



ImageFilter, FilterName, hBmpOutVar, hBmpIn [, X1, Y1, X2, Y2, option]


[결과값]

ErrorLevel = 0 : 명령어 정상 실행

ErrorLevel = 1 : 명령어 실행 오류

ErrorLevel = 2 : 필터명 오류 또는 해당필터의 필수옵션 누락

 

[필터이름 및 전용옵션]

Gray : 그레이 필터

Edge : 엣지 필터

Sharpen : 샤픈 필터

EdgeSharpen : 엣지샤픈 필터

Emboss : 엠보싱 필터

Blur : 블러 필터

MotionBlur : 모션블러 필터

Threshold : 임계값을 기준으로 흑백이미지를 만듭니다.

*ThresholdNN : 임계값, 미지정시 적정 임계값 자동지정, NN=0~255

AdaptThreshold : 적응형 임계필터로 흑백이미지를 만듭니다.

*AdaptRectNN : NN값은 양의정수로 픽셀별 적응면적 설정

*AdaptCaseNN : NN값이 양수일때는 흰색영역이 음수일때는 검은색영역이 증가

BoundaryFill : 시작픽셀과 인접한 시작픽셀과 같은색상을 가진 모든픽셀을 지정한 색상으로 교체합니다.

*xNN,*yNN : 시작픽셀 좌표(필수옵션)

*FillColorNN : 새로 칠할 RGB 컬러값(필수옵션)

ex) *FillColorWhite *FillColor0xFFFFFF

*BoundaryColorNN: 경계선 컬러값, 이 옵션 존재시 경계선을 찾아 내부컬러 교체

*NearVariation : 시작픽셀이 아닌 확장중인 픽셀끼리 비교하여 공차값 적용(object 속성일때 형식 NearVariation:true)

*NN : 색상비교 공차값, NN=0~255(object 속성일때 형식 variation:NN)

BoundaryClean : 검색컬러로 이루어진 인접픽셀군의 크기가 지정된 크기 이하일 경우 새로운 컬러값으로 교체합니다.

*SearchColorNN : RGB 검색컬러(필수옵션)

ex) *SearchColorWhite *SearchColor0xFFFFFF

*FillColorNN : 새로 칠할 RGB 컬러값(필수옵션)

ex) *FillColorWhite *FillColor0xFFFFFF

*SizeMaxNN : NN값은 양수이며 해당 크기 이하의 검색컬러로 이루어진 픽셀군을 찾음(필수옵션)

*UseBoundaryColor : 검색컬러를 경계선 컬러값으로 사용한다는 의미(object 속성일때 형식 UseBoundaryColor:true)

*NN : 색상비교 공차값, NN=0~255(object 속성일때 형식 variation:NN)


[공통옵션]

*WH : X2, Y2를 가로 세로값(픽셀수)으로 사용합니다.

*HBmpNotDel : 기본적으로 명령어 수행 후 hBmpIn 핸들이 소멸하지만, 이 옵션 사용시 핸들이 유지 됩니다.

*AreaCut : X1, Y1, X2, Y2 필터효과 적용범위가 지정된 경우 해당영역의 이미지만 잘라서 출력됩니다.


[사용예]
ex1) 단일필터 개별 적용
CoordMode, Pixel, Screen
ImageGet, hBitmap, 0,0,500,500  ;스크린좌표기준 캡쳐
ImageFilter, Edge, hBitmap, hBitmap
ImageFilter, Gray, hBitmap, hBitmap
SaveHBITMAPToFile(hBitmap, "_filterTest.bmp")
DllCall("DeleteObject", "UPtr",hBitmap)

SaveHBITMAPToFile(hBitmap, sFile)
{
  VarSetCapacity(DIBSECTION, A_PtrSize=8? 104:84, 0)
  NumPut(40, DIBSECTION, A_PtrSize=8? 32:24,"UInt") ;dsBmih.biSize
  DllCall("GetObject", "UPTR", hBitmap, "int", A_PtrSize=8? 104:84, "UPTR", &DIBSECTION)
  hFile:= DllCall("CreateFile", "UPTR", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "int64P", 0x4D42|14+40+(biSizeImage:=NumGet(DIBSECTION, A_PtrSize=8? 52:44, "UInt"))<<16, "Uint", 6, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "UPTR", &DIBSECTION + (A_PtrSize=8? 32:24), "Uint", 40, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "Uint", NumGet(DIBSECTION, A_PtrSize=8? 24:20, "UPtr"), "Uint", biSizeImage, "UintP", 0, "Uint", 0)
  DllCall("CloseHandle", "UPTR", hFile)
}

ex2) 배열을 이용한 복수필터 적용
   filterList := [ {filter:"Sharpen"}, {filter:"Gray"}, {filter:"AdaptThreshold", AdaptRect:7, AdaptCase:3} ]

   ImageFilter, % filterList, hBitmap, hBitmap

[테스트 스크립트]

Test_이미지필터.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

이미지필터_테스트.zip




Posted by 와이로

 

 

;이미지 파일에서 메모리로 이미지 로딩하기

bmpFile = %A_ScriptDir%\Image\IL_Other.bmp

hBitmap := DllCall("USER32\LoadImage", Ptr,0, Str,bmpFile, Uint,0, Int,0, Int,0, Uint,0x10 | 0x2000, Ptr)


;----------------------------------------------------------------------------------
;클립보드에서 비트맵 복사 후 HBitmap 핸들로 반환

;www.autohotkey.com/forum/viewtopic.php?t=35242
CreateHBitmapFromClipboard()
{
  If DllCall("IsClipboardFormatAvailable", UInt,2 )
    DllCall( "OpenClipboard", UInt,0 ), tBM := DllCall("GetClipboardData", UInt,2 )
    , hBM := DllCall( "CopyImage", UInt,tBM, UInt,0, Int,0,Int,0, UInt,0x2000, UInt )
    , DllCall( "CloseClipboard" )
  return hBM ? hBM : 0
}

 

;----------------------------------------------------------------------------------

;메모리에 로딩된 BMP파일을 읽어 HBitmap핸들로 반환
CreateHBitmapFromVar(ByRef bmpVar)
{
  WinGet, hwnd, ID, ahk_class Progman
  hDC := DllCall("USER32\GetDC", Ptr,hwnd, Ptr)
  hBMP := DllCall( "CreateDIBitmap", UInt,hDC, UInt,(bmiHAddr:=&bmpVar+14)
       ,UInt,(CBM_INIT:=4), UInt,&bmpVar+NumGet(&bmpVar,10), UInt,&bmpVar+14, UInt,(DIB_PAL_COLORS:=1) )
  DllCall("ReleaseDC", Ptr,hwnd, Ptr,hDC, Uint)
  return hBMP
}

 

;----------------------------------------------------------------------------------

;메모리에 로딩된 BMP파일을 읽어 pBitmap핸들로 반환 (Gdip 라이브러리 필요)
CreateBitmapFromVar(ByRef bmpVar)
{
  WinGet, hwnd, ID, ahk_class Progman
  hDC := DllCall("USER32\GetDC", Ptr,hwnd, Ptr)
  hBMP := DllCall( "CreateDIBitmap", UInt,hDC, UInt,(bmiHAddr:=&bmpVar+14)
       ,UInt,(CBM_INIT:=4), UInt,&bmpVar+NumGet(&bmpVar,10), UInt,&bmpVar+14, UInt,(DIB_PAL_COLORS:=1) )
  pBitmap := Gdip_CreateBitmapFromHBITMAP(hBMP)
  DllCall("ReleaseDC", Ptr,hwnd, Ptr,hDC, Uint)
  DllCall("DeleteObject", Ptr,hBMP, Uint)
  return pBitmap
}

 

;----------------------------------------------------------------------------------

;비트맵을 파일로 저장
SaveHBITMAPToFile(hBitmap, sFile)
{
  VarSetCapacity(DIBSECTION, A_PtrSize=8? 104:84, 0)
  NumPut(40, DIBSECTION, A_PtrSize=8? 32:24,"UInt") ;dsBmih.biSize
  DllCall("GetObject", "UPTR", hBitmap, "int", A_PtrSize=8? 104:84, "UPTR", &DIBSECTION)
  hFile:= DllCall("CreateFile", "UPTR", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "int64P", 0x4D42|14+40+(biSizeImage:=NumGet(DIBSECTION, A_PtrSize=8? 52:44, "UInt"))<<16, "Uint", 6, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "UPTR", &DIBSECTION + (A_PtrSize=8? 32:24), "Uint", 40, "UintP", 0, "Uint", 0)
  DllCall("WriteFile", "UPTR", hFile, "Uint", NumGet(DIBSECTION, A_PtrSize=8? 24:20, "UPtr"), "Uint", biSizeImage, "UintP", 0, "Uint", 0)
  DllCall("CloseHandle", "UPTR", hFile)
}

 

Posted by 와이로

RunWait 명령어의 기능을 확장 했습니다.



RunWait , Target [, WorkingDir, option, OutVarPID, OutVarStdOut, OutVarStdOutSize]

 

[추가 변수]

OutVarStdOut : 실행시킨 프로세스가 종료되기 전까지의 표준출력 데이터가 저장되는 변수

OutVarStdOutSize : OutVarStdOut 변수에 저장된 데이터의 크기

 

[기존옵션]

Max|Min|Hide|UseErrorLevel


[추가옵션]
TimeoverN : 타임오버시 실행시킨 프로세스 강제종료, N 값은 초단위 숫자

- adb.exe 같은 콘솔프로그램을 실행시킬 경우 대부분 짧은시간내에 종료되지만 오류등으로 종료가 되지 않는 경우가 있습니다. 이럴때 timveover3 옵션을 사용해주면 3초가 초과될시 강제종료가 됩니다.(되도록 강제종료되는 상황이 안생겨야 정상이겠지요)

 

[결과값] - UseErrorLevel 옵션 있을시에만 유효

ErrorLevel = 0 : 실행시킨 프로세스가 정상종료
ErrorLevel = 1 : 프로세스 실행실패
ErrorLevel = 2 : 실행시킨 프로세스가 타임오버로 강제종료됨
ErrorLevel = 3 : 실행시킨 프로세스의 표준출력데이터 읽기 실패 (OutVarStdOut 변수가 있을시에만 유효)

 

 


 

Timeover 옵션 사용 예

 

;5초내에 실행된 메모장이 종료되지 않을시 강제종료

tick := A_TickCount

RunWait, Notepad.exe,, min timeover5
MsgBox % A_TickCount - tick "ms"

 

 

 

Posted by 와이로

 

ImageSearch 명령어 확장기능 설명 바로가기

 

 

이번 예제 스크립트는 '다음팟 플레이어' 를 이용한 동영상 속 이미지를 검색하는 방법입니다. 팟플레이어는 단축키(Ctrl+C)로 현재 프레임의 원본 이미지를 클립보드에 저장 할 수 있습니다. 이걸 이용해 동영상에서 검색할 이미지를 찾는 방법을 알아보겠습니다.

 

간혹 단축키가 다를 수 있습니다.

단축키 확인 방법 : 메뉴 -> 영상 -> 영상 캡쳐 -> 현재 화면 복사(원본크기)  Ctrl+C

 

 

 

 

찾아야할 이미지 만드는 법 : 동영상 재생 후 이미지가 있는 프레임에서 '현재 화면 복사' 단축키를 사용해 이미지를 캡춰 한 후 그림판에 붙여넣기 후 필요한 이미지를 잘라내면 됩니다.

 

1. 이 스샷은 동영상에서 찾아낼 이미지를 표시 한 스샷입니다.

 

 

 

2. 아래 스샷은 동영상 재생 중 검색대상 이미지를 발견에 성공했을때를 찍은 스샷입니다. 검색성공시 '스페이스' 키로 바로 재생을 멈추게 해봤습니다.

 

검색대상 위치가 비어있는 이유는 클립보드를 통한 이미지서치가 동영상 재생보다 더 빨라서 입니다. 다시 재생 시키면 바로 해당위치에 검색대상이미지가 나타나는걸 볼수 있습니다.

 

 

 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

팟플레이어_동영상이미지서치_Test.zip

 

 

 

<스크립트>

 

searchImg = 찾는이미지.bmp
movieFile = TestMovie.avi

 

;매크로 종료
F2::ExitApp

 

;동영상 감시 시작
F1::
  ;레지스트리에서 팟플레이어 설치경로 얻기
  RegRead, player_path, HKCU, Software\DAUM\PotPlayer, ProgramPath
  if !player_path
  {
    MsgBox, 팟플레이어 등록정보를 찾을 수 없어 프로그램을 종료합니다.
    ExitApp
  }
  
  ;팟플레이어 실행
  Run, "%player_path%" "%movieFile%"
  sleep, 2000

 

  loop
  {
    ;팟플레이어 체크
    IfWinNotActive, ahk_class PotPlayer
    {
      sleep, 100
      WinActivate, ahk_class PotPlayer
      continue
    }
    
    ;팟플레이어 '현재프레임 클립보드로 복사' 단축키 체크하세요 : Ctrl+C
    Send, ^c
    
    ;압축률 또는 해상도가 높은 동영상은 sleep을 충분히 걸어줘야 팟플레이어에 렉이 안생깁니다.
    sleep, 100
   
    hBitmap := CreateHBitmapFromClipboard()

 

    ;*TargetHBmp 옵션은 HBITMAP 핸들의 비트맵을 이미지서치 대상으로 설정하며

    ;이미지서치 명령 후 비트맵 핸들을 자동 초기화 시키는 옵션입니다.
    ImageSearch, sx,sy, 0,0,0,0, *TargetHBmp%hBitmap% *50 %searchImg%
    if !ErrorLevel
    {
      ;이미지서치 성공시 팟플레이어 일시정지
      Send, {Space}
     
      MsgBox % "found = " sx "," sy
      ExitApp
    }
  }
return

 

;클립보드 이미지를 HBITMAP 으로 반환

CreateHBitmapFromClipboard()
{
  If DllCall("IsClipboardFormatAvailable", UInt,2 )
    DllCall( "OpenClipboard", UInt,0 ), tBM := DllCall("GetClipboardData", UInt,2 )
    , hBM := DllCall( "CopyImage", UInt,tBM, UInt,0, Int,0,Int,0, UInt,0x2000, UInt )
    , DllCall( "CloseClipboard" )
  return hBM ? hBM : 0
}

 

 

 

 

 

 

 

 

 

Posted by 와이로

ImageListSearch 명령어 설명 바로가기

 

이 샘플 스크립트는 설명의 편의를 위해 검색대상을 화면이 아닌 이미지파일로 했습니다.

SearchTarget_....bmp : 일련의 숫자 이미지가 들어있는 이미지 파일

imglist_number.bmp : 0~9까지의 파트이미지가 세로로 연결된 이미지리스트(파트사이즈 5x8)

 

 

 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

ImageListSearch숫자추출_테스트.zip

 

 

 

<스크립트 : SearchTarget_오랜지컬러숫자추출.ahk>

 

color := 0xFFB400                  ;오랜지색 RGB
imageList = imglist_number.bmp   ;이미지리스트 경로 (흰색의 5x8 픽셀로된 10개의 숫자 이미지리스트)
searchTarget = SearchTarget_오랜지컬러숫자추출.bmp     ;검색대상 경로


;검색대상에 있는 숫자컬러와 이미지리스트의 숫자컬러가 다르므로
;이미지리스트의 숫자컬러를 검색대상의 숫자컬러로 교체해 줍니다.

ImageGet, hImgList,,,,, imageList   ;이미지리스트파일을 로딩

ColorReplace, hImgList, hImgList, 0xFFFFFF, color   ;흰색(0xFFFFFF) -> 오랜지색(0xFFB400) 교체

 

;검색시작좌표와 마지막좌표 설정
ImageGet,,,,,, searchTarget,,size
curx := 0  ,  cury := 0
endx := size.width - 1  ,  endy := size.height - 1

loop
{
  ;x축 검색영역 벗어날시 루프 종료
  if (curx>endx)
    break
  
  ;5x8 픽셀사이즈의 파트이미지 10개로 구성된 이미지리스트로 대상 검색
  ;이미지리스트파일 대신 이미지리스트비트맵핸들을 사용하므로 *HBmpNotDel 옵션 추가
  ImageListSearch, sx,sy,si, curx,cury,endx,endy, *UseZeroIndex *Listmax10 *TransBlack *Transnot%color% *FixW *ValidW *Obj *TargetFile<%searchTarget%> *HBmpNotDel %hImgList%
  if !ErrorLevel
  {
    str .= si.index
    curx := si.validx + si.validw
  }
  ++curx
}

 

;이미지리스트 비트맵 핸들의 사용이 끝났으므로 핸들을 초기화합니다.
DllCall("DeleteObject", Ptr,hImgList)

 

;찾은숫자 메시지박스로 표시

MsgBox % "찾은숫자 = " str

 


/*


 < ImageListSearch 명령에 사용된 옵션 설명 >

 

*UseZeroIndex : 이미지리스트의 시작인덱스를 1이 아닌 0을 사용한다.

*Listmax10 : 이미지리스트가 10개의 파트이미지로 구성되있음을 표시합니다.

*TransBlack : 이미지리스트의 배경색이 검은색임을 표시합니다.(검색제외 색상)

*Transnot%color% : 각 파트이미지로 검색할시 파트이미지의 검은색 영역에 color 변수의 색값이 없어야 함을 표시합니다.

*FixW : 검색영역을 검색시작좌표에서 파트이미지의 가로사이즈(W)만큼으로 제한합니다.

검색영역을 무시하고 일정영역 만큼만 각 파트이미지를 대조해 보고 서치를 끝내는 옵션입니다.

*ValidW : 파트이미지의 가로영역의 유효이미지를 제외한 부분을 최대한 제거합니다.

숫자 1의 경우 가로 5픽셀이지만 이 옵션 효과로 인해 가로 유효영역인 2픽셀만 검색에 사용됩니다. *Trans 옵션도 투명영역을 배제하고 유효영역만 검색하는데 뭐가 다르냐고 의문을 품는 분들을 위해 설명하자면 *Trans 옵션은 실제 검색용으로 쓰는 이미지 사이즈를 줄여주지는 않지만 *Valid 옵션은 이미지 크기가 바뀐다고 보면됩니다.

*Obj : 출력변수 si 를 Object 출력변수로 설정합니다.

*TargetFile<%searchTarget%> : searchTarget 변수의 파일을 대상으로 검색합니다.

파일대상일때는 경로를 < > 로 둘러싸줘야 합니다.

*HBmpNotDel : 검색소스파일대신 비트맵핸들값으로 검색한다는 것을 표시하는 옵션입니다. (*HBmp옵션과 동일하지만 핸들을 소멸시키지 않습니다.)
 

*/

 


 

 

 

 

 

 

 

 

Posted by 와이로

ImageList 명령어는 서브커맨드에 따라 이미지리스트에 이미지를 추가하거나 가져오거나 설정하는 명령어입니다. ImageListSearch 에 사용하는 이미지리스트를 만들때 사용하면 유용합니다.



ImageList , sub-command, hBmpListVar, hBmpVar, [option]

 

[결과값]
ErrorLevel = 0: 명령어수행 완료
ErrorLevel = 1: 명령어수행 실패
ErrorLevel = 2: 이미지리스트 오류 (Get,Set 에서만 사용하며 필수옵션이 없어도 발생)

 

[변수]
hBmpListVar : 이미지리스트 비트맵 핸들용 변수
hBmpVar : 파트이미지 비트맵 핸들용 변수

 

[서브커맨드]
Add : 이미지리스트에 파트이미지를 추가합니다.

(출력변수 : hBmpListVar ,  입력변수 : hBmpVar)

Get : 이미지리스트에서 선택한 파트이미지를 가져옵니다.

(출력변수 : hBmpVar     ,  입력변수 : hBmpListVar)

Set : 이미지리스트의 파트이미지를 교체합니다.

(출력변수 : hBmpListVar ,  입력변수 : hBmpListVar, hBmpVar)

 

[Add 서브커맨드 옵션]
*WidthList : 가로이미지리스트 일때 사용

*SrcNotDel : 명령어 사용후 'hBmpVar' 변수의 비트맵핸들을 초기화 하지 않음
*BackgroundN : N값은 컬러명 또는 RGB 값

 (ex. *BackgroundBlack, *BackgroundWhite, *Background0xFFFFAA)

 

[Get 서브커맨드 옵션]
*ListMaxNN : 필수옵션, NN값은 이미지리스트상의 파트이미지 총개수
*SelectNN : 필수옵션, NN값은 1부터 시작하는 파트이미지 인덱스
*WidthList : 가로이미지리스트 일때 사용
*ListNotDel : 명령어 사용후'hBmpListVar' 변수의 비트맵핸들을 초기화 하지 않음

*UseZeroIndex : 이미지리스트의 시작인덱스를 1이 아닌 0을 사용


[Set 서브커맨드 옵션]
*ListMaxNN : 필수옵션, NN값은 이미지리스트상의 파트이미지 총개수
*SelectNN : 필수옵션, NN값은 1부터 시작하는 파트이미지 인덱스
*WidthList : 가로이미지리스트 일때 사용
*ListNotDel : 명령어 사용후 'hBmpListVar' 변수로 입력받은 비트맵핸들을 초기화 하지 않음

*SrcNotDel : 명령어 사용후 'hBmpVar' 변수의 비트맵핸들을 초기화 하지 않음

*UseZeroIndex : 이미지리스트의 시작인덱스를 1이 아닌 0을 사용

[주의]

 - 출력변수로 받은 HBITMAP 핸들은 사용이 끝난 후 초기화 해주세요. (ex. DllCall("DeleteObject", Ptr,hBitmap)

 - ImageListSearch 명령어에 사용할 이미지리스트를 만들때는 *WidthList 옵션을 넣지 마세요.

 


 

아래 샘플스크립트는 F1 키로 마우스 위치의 이미지를 캡춰 한후 이미지리스트에 계속 추가 할 수 있으며 F2 키로 이미지리스트를 비트맵파일로 저장하는 스크립트 입니다.

 

 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

ImageList명령어_테스트.zip

 

 

<테스트 스크립트중 일부>

 

CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
captureWidth  := 20
captureHeight := 20

 

RectWindow:
  Gui 2: +LastFound
  Gui 2: -Caption +AlwaysOnTop
  Gui 2: Color, EEAA99
  Gui 2: Add, Text, w%captureWidth% h%captureHeight% Border vBorder hwndhwndBorder
  Gui 2: Show
  WinSet, TransColor, EEAA99 255
  hwndRectWin := WinExist()
  WinGetPos, borderx,bordery,,, ahk_id %hwndBorder%
  WinGetPos, rectwinx,rectwiny,,, ahk_id %hwndRectWin%
  gapx := borderx-rectwinx  ,  gapy := bordery-rectwiny
  Loop
  {
    MouseGetPos, capx,capy
    capx -= gapx  ,  capy -= gapy+captureHeight
    WinMove, ahk_id %hwndRectWin%,, capx, capy
    Tooltip, F1:이미지리스트추가
    sleep, 10
  }
return


;현재 영역 캡춰 후 이미지리스트에 추가
F1::
  WinGetPos, x,y,w,h, ahk_id %hwndBorder%
  ImageGet, hBitmap, x+1,y+1,w-2,h-2,, *WH
  ImageList, Add, hImageList, hBitmap   ;hBitmap 핸들은 ImageList 명령어 사용 후 초기화 됩니다.
  sleep, 300

return


;이미지리스트 파일로 저장 후 스크립트 종료
F2::
  if hImageList
  {
    SaveHBITMAPToFile(hImageList, imgListFile := "캡춰이미지리스트.bmp")
    DllCall("DeleteObject", Ptr,hImageList)
    hImageList =
    MsgBox, 캡춰한 이미지리스트를 %imgListFile%에 저장했습니다.
  }
  ExitApp
return

 

 

 

Posted by 와이로

'디컴방지 컴파일러'가 설치된 경우는 아래 파일을 다운로드해 사용할 필요가 없습니다.


AutoHotkey.zip

업데이트 : 2019-05-16

Autohotkey.zip 파일만 단독으로 받아 사용시 목표 스크립트를 AutoHotkey.exe 에 매번 드래그앤드롭해 실행하는 것이 번거롭다면 AutoHotkey.exe 이름을 목표 ahk 스크립트 파일 이름과 동일하게 바꾸고 목표 스크립트가 위치한 폴더에 넣고 실행하면 드래그앤드롭 없이 바로 실행 가능합니다.


 -> 오토핫키 플러스 명령어 목록 바로가기

'유틸리티' 카테고리의 다른 글

[Ahk+] 오토핫키+ 명령어 적용된 AutoHotkey.exe  (1) 2015.10.07
Pixel Color Picker(스크립트)  (2) 2015.09.05
Posted by 와이로

새 명령어를 Autohotkey C++ 소스에서 추가하려면 6단계의 작업이 필요합니다.

(globaldata.cpp 부분에 영문 코멘트로 설명되어 있습니다.)

 

스크린좌표에 존재하는 윈도우 핸들을 얻는 명령어를 추가 했을 경우를 예로 들겠습니다.

PointGetWindow, x, y , OutWindowVar, [OutControlVar, 1|2|3]

 


1. globaldata.cpp - 명령어구성 추가

{_T("PointGetWindow"), 3, 5, 5, {1, 2, 5, 0}}

- 인자 3, 5, 5 값은 각각 어규먼트 최소개수, 최대개수, 최대개수입니다.
- 인자 {1, 2, 5, 0} 값의 1, 2, 5 는 어규먼트번호이며 해당 어규먼트 입력값이 변수인경우 해당 변수의 값을, 변수가 아닌경우 입력값 그대로 가져옵니다.

- 만약 {1, 2, 5, 0} 자리에 NULL 값이 들어가면 모든 어규먼트 입력값을 변수가 아닌 입력값 그대로 가져옵니다. (4단계에서 입출력 변수로 설정된 인자는 제외)

 

2. defines.h - 액션ID 추가
ACT_POINTGETWINDOW

- 명령어구성 리스트와 일대일 대응하므로 순서가 어긋나면 오류가 발생합니다.

 

3. script.h - Line 클래스 내부에 선언문 추가
ResultType PointGetWindow(int pointx, int pointy, DWORD aOptions);

- 추가 명령어 호출시 동작할 함수의 원형을 선언합니다.

 

4. script.h - 변수 입출력 타입 설정 구문 추가

아래는 3번(OutWindowVar) 과 4(OutControlVar) 어규먼트를 출력변수로 설정하는 방법입니다.

case 2:  // Arg #3
    switch(aActionType)

    {

    ....

    ....
    case ACT_POINTGETWINDOW:

        return ARG_TYPE_OUTPUT_VAR;

    }

    break;

case 3:  // Arg #4
    switch(aActionType)
    {

     ....

     ....
    case ACT_POINTGETWINDOW:
        return ARG_TYPE_OUTPUT_VAR;
    }
    break;

 

5. script.cpp - 명령어로 함수 호출하는 파트 추가

case ACT_POINTGETWINDOW:

    return PointGetWindow(ArgToInt(1), ArgToInt(2), ArgToUInt(5));
 

6. script.cpp - 실제 호출함수 정의

추가된 명령어 호출시 동작할 함수를 구현합니다.

실제 구현시에는 Line::MouseGetPos() 함수를 변경해서 만들었습니다.

ResultType Line::PointGetWindow(int pointx, int pointy, DWORD aOptions)
{

    Var *output_var_parent = ARGVAR3;

    Var *output_var_child = ARGVAR4;


    ....

    ....

    if (!output_var_parent->AssignHWND(parent_under_cursor))
        return FAIL;
}

 

 


 

 

아래는 PointGetWindow 명령어를 추가한 C++ 소스파일입니다.

VC2010 에서 F5 키로 디버깅모드 실행하면 Test.ahk 스크립트 테스트가 가능합니다.

AutoHotkey_L-AddNewCmd.zip

 

 

<테스트 스크립트>

PointGetWindow, 10,10, hwnd
WinMove, ahk_id %hwnd%,, 50,0
MsgBox % hwnd

 

 

<명령어 추가를 위한 소스코드 수정 위치 스샷>

소스코드에서 '명령어추가' 로 검색하시면 모든 수정 위치를 찾을 수 있습니다.

 

 

 

1단계 globaldata.cpp - 명령어구성 추가 위치

 

 

2단계 defines.h - 액션ID 추가 위치

 

 

3단계 script.h - Line 클래스내부 호출함수 선언문 추가 위치

 

 

 

4단계 script.h - 변수타입 설정 위치

입출력 변수 설정이 필요없는 경우는 생략해도 되는 파트이며 변수타입 설정위치는 입출력에 사용될 변수의 위치에 따라 달라집니다. PointGetWindow 명령어의 경우 Arg #3 과 Arg #4 파트에 위치시켜야 해당 변수들이 출력변수로 적용됩니다.

 

 

 

5단계 script.cpp - 명령어로 함수호출하는 파트 추가 위치

 

 

 

6단계 script.cpp - 실제 호출함수 구현

 

 

 

 

 

 


Posted by 와이로

BinToHex 와 HexToBin 명령어는 이진데이터와  HEX문자열(BASE64문자열)간 변환 명령어 입니다. 오토핫키 명령어로 구현 가능하지만 편하고 빠르게 쓰려고 추가한 명령어로 두 명령어 모두 성공시 ErrorLevel 값은 0 실패시 1을 반환합니다.

 

 

BinToHex , OutHexStringVar, binDataVar, binDataSize, [*Base64]

 

binDataVar 변수에 저장된 데이터를 HEX 문자열로 변환시켜 줍니다.

 

[변수]

OutHexStringVar : 변환된 HEX 문자열 출력 변수

binDataVar : 이진데이터가 저장된 입력 변수

binDataSize : 변환시킬 바이트 수

 

[옵션]
*Base64 : 이 옵션 사용시 BASE64 문자열로 변환

 


 

HexToBin , OutBinDataVar, OutBinDataSize, hexStringVar, [*Base64]

 

hexStringVar 변수에 저장된 HEX 문자열을 이진데이터로 변환시켜줍니다.

 

[변수]

OutBinDataVar : 변환된 이진데이터 출력 변수

OutBinDataSize : 변환된 이진데이터 사이즈 출력 변수

hexStringVar : HEX 문자열 입력 변수

 

[옵션]
*Base64 : BASE64 문자열을 이진데이터로 변환시킬때 사용

 

 


 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

BinToHex테스트_소스.zip

 

 

 

<테스트 스크립트>


imageFile = sample.bmp
FileRead, srcData, *c %imageFile%  ;*c 옵션은 파일내용을 그대로 읽어오는 옵션
FileGetSize, srcSize, %imageFile%


;이미지데이터를 HEX 문자열 변환 후 다시 이미지데이터 변환
BinToHex, hexStr, srcData, srcSize
MsgBox,, 이미지데이터를 HEX문자열로 변환한 상태, % hexStr
HexToBin, newData, newSize, hexStr
file := FileOpen("1.HEX문자열-이미지변환.bmp", "w")
file.RawWrite(newData, newSize)
file.Close()


;이미지데이터를 BASE64 문자열 변환 후 다시 이미지데이터 변환
BinToHex, b64Str, srcData, srcSize, *Base64
MsgBox,, 이미지데이터를 BASE64문자열로 변환한 상태, % b64Str
HexToBin, newData, newSize, b64Str, *Base64
file := FileOpen("2.BASE64문자열-이미지변환.bmp", "w")
file.RawWrite(newData, newSize)
file.Close()

 

 

 

 

Posted by 와이로

URLDownloadToVar 명령어는 http:// 또는 https:// 로 시작하는 웹주소의 데이터를 다운로드 후 변수에 저장합니다. 다운로드한 데이터를 파일로 남기고 싶지 않을때 사용하면 좋습니다.



URLDownloadToVar , [*option] Url, DownloadVar [, DownloadSize]

 

[변수]

DownloadVar : 다운로드한 데이터가 저장되는 변수

DownloadSize : 다운로드한 데이터의 사이즈

 

[옵션]

*T : 다운로드한 데이터가 인지 가능한 문자열 인코딩인 경우 시스템 인코딩으로 자동변환

*Pnnn : 다운로드한 데이터가 문자열이고 인코딩 방식을 직접 지정할 때 사용

  ex) *P65001 : UTF-8   ,  그외 코드페이지ID 참조사이트

 

보통은 *T 옵션 만으로 자동 변환이 되야 하지만 BOM 값이 존재하지 않는 경우 *Pnnn 옵션으로 직접 인코딩 방식을 지정해 줘야 합니다. 이진 데이터인 경우는 옵션값을 비워두면 됩니다.

 

 

<테스트 스크립트>

스크립트 테스트는 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 아래의 샘플 스크립트가 작성된 파일을 드래그해서 실행하세요.

 

1. 네이버 메인페이지는 *T 옵션을 사용한 경우 한글이 깨집니다.

URLDownloadToVar, *T http://www.naver.com, downVar, downSize
MsgBox % downVar
 

2. *P65001 옵션으로 UTF-8 인코딩을 지정한 경우 한글이 정상 출력 됩니다.

URLDownloadToVar, *P65001 http://www.naver.com, downVar, downSize
MsgBox % downVar

 

 

Posted by 와이로

이미지리스트서치 명령어는 세로 이미지리스트의 모든 파트이미지를 검색대상 영역에서 순차검색 하며 파트이미지중 한개라도 발견시 해당 좌표와 해당 파트이미지의 인덱스를 반환합니다.

 

이 명령어는 숫자인식이나 문자인식 같은 규격화된 동일크기의 이미지를 연속검색하는 용도로 사용시 효과적입니다.



ImageListSearch , OutputVarX, OutputVarY, OutVarIndex, X1, Y1, X2, Y2, [*option] ImageListFile

 

[결과값]
ErrorLeve = 0 : 이미지리스트 중 검색 성공한 파트이미지 있음
ErrorLeve = 1 : 이미지리스트의 모든 파트이미지 검색값 없음
ErrorLeve = 2 : 이미지리스트 소스 오류, 파일이 존재하지 않거나 HBITMAP 핸들값이 유효하지 않을시 발생
ErrorLeve = 3 : 이미지리스트 상태 오류, *ListMaxNN *SelectN1:N2 값이 잘못 입력되도 이 오류 발생

 

[변수]
OutputVarX, OutputVarY : 검색성공시 이미지 좌표
OutVarIndex : 이미지리스트에서 검색성공한 인덱스번호 (인덱스번호는 0부터 시작)
X1, Y1, X2, Y2 : 검색할 영역 (X2,Y2 값은 *WH옵션으로 사이즈값으로 대체가능)

 

[옵션]
*ListmaxNN : NN값은 이미지리스트상의 파트이미지 총개수

*UseZeroIndex : 이미지리스트의 시작인덱스를 1이 아닌 0을 사용
*WH : X2,Y2값을 가로 및 세로 사이즈 값으로 사용
*n(variantion) : 이미지서치 공차값 0~255 사이의 숫자
*Scan(RB|BR|LT|TL|RT|TR|LB|BL) : 스캔방향 설정 (기본스캔방향은 RB)

  - Scan 옵션에 대한 세부설명은 '이미지서치' 명령어 항목에서 확인하세요.
*Result(LT|LB|RT|RB|Center|Random) : 검색결과 좌표값 설정 (기본값 LT)

  - Result 옵션에 대한 세부설명은 '이미지서치' 명령어 항목에서 확인하세요.
*TransN : 투명컬러값 지정, N값은 컬러명 또는 RGB 값 (ex. *TransBlack, *TransWhite, *Trans0xFFFFAA)
*TransnotN : 투명컬러영역에 없어야할 컬러명 또는 RGB 값 (ex. *TransnotWhite, *Transnot0xFFFFFF)
*HBmp : 'ImageListFile' 입력 부분에 "HBITMAP" 핸들값을 사용 (사용된 핸들은 자동소멸)
*HBmpNotDel : *HBmp 옵션과 같은 기능이지만 사용된 핸들이 그대로 유지된다.
 - 이 옵션 사용시 추후에 핸들값 초기화 필요 (ex. DllCall("DeleteObject", Ptr,hBitmap))
*Obj : 출력변수 'OutVarIndex' 를 출력오브젝트 변수로 사용

 - Object{index, validx, validy, validw, validh, w, h}
*Valid(W|H)|(L|T|R|B) : *TransN 옵션 사용시에만 유효하며, 파트이미지의 외곽 투명영역을 최대한 배제시킴
 - (W|H) : 파트이미지의 가로 또는 세로 축에서 *Valid 옵션처리할 방향 선택 (WH 모두 사용 가능)
 - (L|T|R|B) : 유효이미지의 외곽에 투명컬러영역을 1픽셀단위로 확장할때 사용 (LTRB 모두 사용시 상하좌우 모두 1픽셀단위 확장)
 - ex) *ValidW, *ValidWH, *ValidWLR
*SelectN1:N2 : 이미지리스트중 선택된블럭만 사용할때 사용 (N1 = 시작 파트이미지 인덱스, N2 = 시작인덱스부터 사용할 파트이미지 수)
*Fix(W|H) : 검색시작좌표기준으로 검색대상영역을 이미지리스트의 각 파트이미지 크기로 고정
                 (W: 가로크기고정, H: 세로크기고정, WH: 가로세로모두고정)
*Target(File|HBmp|HBmpNotDel)xx : 이미지서치 대상을 화면이 아닌 파일이나 HBITMAP 핸들로 사용
 - 검색대상이 파일일때 < > 기호로 파일경로를 둘러싸 줄것 : *TargetFile<filePath>

*FilterGray : 대상화면(이미지)의 검색영역 및 검색소스 이미지를 회색톤 이미지로 교체 후 이미지서치를 수행합니다. (추가:151207)

*FIlterMono : 모든 이미지를 흑색과 백색으로만 구성된 모노톤 이미지로 교체 후 이미지서치를 수행합니다. (백색 교체값은 Variation 범위 내의 컬러이며 그외 값은 흑색으로 교체됩니다.) (추가:151212)

 


 

*Valid 옵션에 대한 세부설명

 

*Valid 옵션은 W|H 선두옵션과 L|T|R|B 후미옵션으로 나뉘어져 있습니다.

옵션에 사용된 각 문자는 Width Height  , Left Top Right Bottom 의 앞 글자입니다.

 

후미옵션은 방향에 맞게 선두 옵션에 종속됩니다.

선두가 W 라면 후미는 L|R 만 유효하고 선두가 H 라면 후미는 T|B 만 유효합니다.

선두를 WH 둘다 사용하면 후미도 LTRB 모두 사용가능합니다.

 

 

예를 들어 가로 세로 15x16 픽셀의 파트이미지들로 이루어진 이미지리스트가 있고 *TransWhite 옵션으로 흰색 배경을 투명처리 한 상태로 검색대상 영역에서 이미지서치 한다고 했을때...

 

*Valid 옵션이 없다면 15x16픽셀 전체를 검색대상 영역에서 찾게 됩니다. 이는 검색대상 영역에 Red 컬러의 '가' 글자가 있더라도 그 크기가 15x16 보다 작다면 '가' 파트이미지 부분은 검색 실패 처리되고 이미지리스트의 다음 파트이미지 검색으로 넘어가게 됩니다.

 

*ValidWH 옵션이 있다면 15x16픽셀중 *TransWhite 영역을 배제한 노란색으로 둘러쌓인 가로 세로 9x10 부분의 실제 글자 '가' 이미지만을 검색대상 영역에서 찾게 됩니다. 위에 *Valid 옵션이 없었을때 처럼 검색대상 영역이 15x16픽셀보다 작더라도 실제 Red 컬러의 '가' 이미지만 있다면 이미지서치 성공으로 처리되는 것입니다.

 

*ValidW 옵션 라면 15x16픽셀 중 가로영역만 유효픽셀 설정되므로 실제 검색에 사용되는 픽셀은 가로 세로 9x16 픽셀입니다.

*ValidH 옵션 이라실제 검색에 사용되는 유효픽셀은 가로 세로 15x10 픽셀이 됩니다.

 

 

*ValidWH 이후에 붙는 L|T|R|B 옵션은 유효영역을 1픽셀 단위로 각 방향으로 확장시켜줍니다.

 

 

왼쪽 노란색으로 둘러쌓인 픽셀영역은 *ValidWHLTRB 옵션일때의 유효픽셀 영역이고

오른쪽 파란색으로 둘러쌓인 픽셀영역은 *ValidWHR 옵션일때의 유효픽셀 영역입니다.

 

*Valid 옵션에서 L|T|R|B 후미옵션은 거의 쓸 일이 없지만 글자간 공백까지 이미지서치기준에 넣을때 유용한 옵션입니다.

 


 

 

*Obj 옵션에 대한 세부 설명

 

 

*Obj 옵션은 OutVarIndex 변수를 오브젝트출력 변수로 사용 할 수 있도록 하는 옵션입니다.

 

반환되는 validx validy validw validh 값은 *Valid 옵션 유무에 관계없이 *ValidWH 옵션을 적용했을때의 픽셀영역을 기준으로 합니다.

 

OutVarIndex.index  : 검색에 성공한 파트이미지 인덱스 번호 (1부터 시작)

OutVarIndex.validx : 검색된 이미지의 x축 좌표값에서 유효픽셀 시작점만큼 이동한 값으로

위의 '가' 이미지를 0,0 좌표에서 찾았다고 했을시 validx 값은 3이 됩니다.

OutVarIndex.validy : 검색된 이미지의 y축 좌표값에서 유효픽셀 시작점만큼 이동한 값

OutVarIndex.validw : 가로방향 유효픽셀 수 (노란색 영역의 가로픽셀 개수)

OutVarIndex.validh : 세로방향 유효픽셀 수 (노란색 영역의 세로픽셀 개수)

OutVarIndex.w : 파트이미지 가로크기

OutVarIndex.h : 파트이미지 세로크기

 


 

아래 파일은 이미지리스트서치 테스트용 스크립트입니다.

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'   위에 드래그해서 실행하세요.

이미지리스트서치_테스트.zip

 

 

이 테스트 스크립트 구성은 아래와 같은 텍스트를 추출할 대상 이미지 파일과 해당한글폰트가 저장된 이미지리스트 파일로 구성되 있습니다.

ps. 텍스트추출용 이미지 파일은 '던파 경매장 아이템 및 가격 읽기 테스트' 스크립트로 생성했습니다.

 

 

 

<스크립트>

 

#SingleInstance Force
^\::ExitApp


/*

이 스크립트는 이미지리스트서치용 테스트 스크립트이며 글자이미지에서 텍스트를 추출합니다.
이미지리스트서치 명령어는 사용방법이 복잡하므로 실제 자신의 스크립트에 적용하기 전에 충분한 테스트가 필요합니다.

 

<구성>
1. imagelist_한글폰트.bmp : 동일크기의 10x10크기의 11223개 파트이미지로 이루어진 폰트이미지리스트
2. SearchTable.bmp : 텍스트 추출할 글자 이미지가 있는 이미지파일

*/


F1::
  imageListFile = imagelist_한글폰트.bmp   ;한글이미지들이 저장된 이미지리스트 파일
  searchFile = SearchTable.bmp              ;검색대상 이미지 파일
  colorFont := 0xFFFFFF                          ;글자색 : 힌색
  spacePixelCnt := 5                               ;띄어쓰기 픽셀 개수
  
  ;이미지크기 얻기
  ImageGet,,,,,, searchFile,, imgSize
  
  ;검색대상이 화면이 아닌 이미지파일이므로 TargetFile 옵션 사용
  ;글자이미지가 시작되는 y축 좌표 얻기
  PixelSearch, sx,starty, 0,0,0,0, colorFont,, *TargetFile<%searchFile%>
  ;글자이미지가 시작되는 x축 좌표 얻기
  PixelSearch, startx,sy, 0,0,0,0, colorFont,, *TargetFile<%searchFile%> *ScanBR
  
  ;글자시작점 못찾을시 종료
  if (startx="" or starty="")
  {
    MsgBox, 글자시작점 찾기 실패
    return
  }
  
  ;이미지에서 글자 추출 시작
  curx := startx  ,  cury := starty  ,  endx := imgSize.width-1  ,  endy := starty + 10
  text =
  loop
  {
    ImageListSearch, sx,sy,so, curx,cury,endx,endy, *TargetFile<%searchFile%> *Listmax11223 *UseZeroIndex *ValidWH *FixW *Obj *TransBlack *Transnot%colorFont% %imageListFile%
    
    ;*TargetFile<%searchFile%> : 검색대상이 화면이 아닌 이미지파일인 경우 사용하는 옵션
    ;*Listmax11223 : *ListmaxNN옵션으로 NN은 이미지리스트의 파트이미지 총 개수를 나타낸다.

    ;*UseZeroIndex : 이미지리스트의 시작인덱스를 1이 아닌 0을 사용한다.
    ;*ValidWH : 이미지리스트의 각 파트이미지의 크기를 재조정한다. (투명값으로 처리된 외곽 픽셀영역을 최대한 제거)
    ;*FixW : 검색대상영역의 시작좌표를 기준으로 검색할 가로영역을 파트이미지크기에 맞게 고정한다. (*Valid 옵션의 영향도 받는다)
    ;*Obj : so 변수는 원래 검색성공한 파트이미지의 인덱스 번호를 반환하지만, 이 옵션으로 인해 세부항목이 포함된 오브젝트 변수를 반환한다.
    ;*TransBlack : 이미지리스트의 검은색영역을 투명색 처리
    ;*Transnot%colorFont% : 이미지리스트의 각 파트이미지를 검색영역에서 검색시, colorFont 컬러값이 투명처리된 픽셀에 존재할시 노매치 처리한다.
    ;(비슷한 글자 오인 추출을 막음 : ex. '각' 과 '감')
    
    if !ErrorLevel
    {
      ;*Obj 옵션으로 인해 so 출력변수는 인덱스값 뿐만 아니라 찾은파트이미지의 세부정보를 저장한 오브젝트를 반환함
      text .= GetChar_Hangle(so.index)  ;추출한 글자 저장
      curx := so.validx + so.validw       ;x축 검색시작점을 찾은글자의 다음픽셀로 교체
      
      ;현재검색점에서 다음글자가 나타나는 지점을 찾기위해 픽셀서치
      ;*ScanBR 옵션은 '상측에서 하단' 그리고 '좌측에서 우측' 으로 검색하므로 처음 나타나는 x축 글자픽셀 위치를 정확히 찾을수 있음
      PixelSearch, nextx,sy, curx,cury,endx,endy, colorFont,, *TargetFile<%searchFile%> *ScanBR
      if !ErrorLevel
      {
        spaceCnt := (nextx-curx) // spacePixelCnt   ;띄어쓰기 개수 얻기
        curx := nextx   ;x축 검색시작점을 발견된 다음글자 시작점으로 교체
        
        ;띄어쓰기 적용
        loop % spaceCnt
          text .= " "
      }
      else
        break   ;발견된 글자가 없을시 루프 종료
    }
  }
 
  msg =
  (LTrim
    글자시작점 = %startx%,%starty%
    추출한글자 = %text%
  )
  MsgBox % msg
return

 

;------------------------------------------------------------
;이미지 배열인덱스로 한글 한글자를 반환한다.
;반환값 실패시 "" 빈문자열 반환
GetChar_Hangle(index)
{
  ;한글이미지리스트의 파트이미지 수 = 11223 (완성한글글자수 11172자 + 개소한글글자수 51자)
  static asc_가 = 44032     ;부터 11172개 글자
  static asc_힣 = 55203
  static asc_ㄱ = 12593     ;부터 51개 글자
  static asc_ㅣ = 12643
 
  asc := asc_가 + index
  if (index>=11172)
    asc := index - 11172 + asc_ㄱ
  return Chr(asc)
}

 

 

 



< ImageListSearch 추가 예문 링크 >

 

 -> ImageListSearch 예문1 - 이미지에서 연속된 숫자 추출

 

Posted by 와이로

기존 픽셀서치 명령에 몇가지 유용한 옵션을 추가하였습니다.



PixelSearch , OutVarX, OutVarY, X1, Y1, X2, Y2, ColorID [, Variation, option, OutVarExceptColor]

 

[결과값]

ErrorLevel = 0 : 검색성공

ErrorLevel = 1 : 검색실패

ErrorLevel = 2 : 오류

 

[기존변수]
OutVarX, OutVarY : 검색성공시 픽셀 좌표

X1, Y1, X2, Y2, : 검색대상 영역 (*WH 옵션시 X2, Y2 값은 가로 및 세로 크기값)

ColorID : 검색할 컬러값 (기본 컬러 포맷은 GRB)

Variation : 컬러 공차값으로 0~255 사이의 숫자

 

[추가변수]

OutVarExceptColor : *Except 또는 *ExceptLine 옵션 사용시에만 유효한 변수이며 검색된 예외컬러가 존재하는 픽셀 좌표의 컬러값을 반환

 

[기존옵션 - 되도록 * 기호를 붙인 *Fast, *RGB 같은 사용 방식을 권장]
*Fast : 오토잇에서 업그레이드된 검색방식을 사용하기 위한 옵션
*RGB : 입력된 검색컬러를 RGB 컬러값으로 적용

 

[추가옵션 - 추가옵션 사용시 *Fast 옵션 자동 사용]
*WH : X2,Y2값을 가로 및 세로 사이즈 값으로 사용
*Scan(RB|BR|LT|TL|RT|TR|LB|BL) : 스캔방향 설정 (기본스캔방향은 RB)
*Except : 입력 컬러값을 제외한 컬러값이 존재하는 픽셀좌표 반환
*ExceptLine : 입력 컬러값이 존재하지 않는 스캔라인의 첫번째 픽셀좌표 반환
*Target(File|HBmp|HBmpNotDel)xx : 이미지서치 대상을 화면이 아닌 파일이나 HBITMAP 핸들로 사용
- 검색대상이 파일일때 < > 기호로 파일경로를 둘러싸 줄것 : *TargetFile<filePath>

 


 

*Scan 옵션에 대한 세부설명

 

이미지서치나 픽셀서치에서 *ScanXX 옵션으로 설정 가능하며 검색시작점과 검색방향의 우선순위를 지정하는데 사용합니다. 오토핫키의 기본 스캔방향은 왼쪽상단에서 오른쪽으로 그리고 아래로 진행하는 방식이며 *ScanRB 옵션과 같습니다.

 

아래 스샷의 스캔 진행방향은 1번이 선두 스캔방향이며 2번이 후순위 스캔방향입니다.

 

 


 

 

*Except 옵션

픽셀서치에서 *Except 옵션으로 설정 가능하며 Blue 컬러가 입력컬러인 경우 Blue 컬러를 제외한 다른 컬러값이 발견된 픽셀 좌표를 반환

- 위의 샘플픽셀배열에서 기본스캔방향일 경우 반환 좌표는 x=8 , y=0

 

*ExceptLine 옵션

픽셀서치에서 *ExceptLine 옵션으로 설정 가능하며 Blue 컬러가 입력컬러인 경우 Blue 컬러가 존재하지 않는 스캔라인의 첫번째 픽셀 좌표를 반환

- 위의 샘플픽셀배열에서 기본스캔방향일 경우 반환 좌표는 x=0 , y=1

 

 


 

 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

PixelSearch_Test(Search_ColorBlock).zip

 

 

이 스크립트는 특정컬러블럭(적색)의 좌상단 좌표를 모두 찾는 스크립트입니다.
화면검색용으로 바꾸시려면 PixelSearch 명령 라인의 *TargetFile<%searchFile%> 옵션을 전부 제거해 주시고 startx, starty, endx, endy 변수에 화면좌표를 설정해 주시면 됩니다.

 

 

 

 

 

<테스트 스크립트>

 

result := {}
searchColor := 0x241CED    ;찾을 컬러값 = 적색
searchFile = SearchTable.bmp
ImageGet,,,,,, searchFile,, imgSize   ;이미지사이즈 얻기

 

startx := 0
starty := 0
endx := imgSize.width-1
endy := imgSize.height-1

 

cury := starty
loop
{
  ;y축좌표가 범위를 벗어난 경우 루프 종료
  if (cury>endy)
    break
 
  curx := startx
  loop
  {
    ;검색할 컬러 찾기
    PixelSearch, sx,sy, curx,cury,endx,cury, searchColor,, *TargetFile<%searchFile%>
    if !ErrorLevel
    {
      ;윗픽셀과 같은색이 아닐경우 다른블럭으로 인식
      PixelGetColor, color, sx,sy-1, *TargetFile<%searchFile%>
      if (color<>searchColor)
      {
        obj := {x:sx, y:sy}
        result.Insert(obj)
      }
      curx := sx + 1
      cury := sy
      
      ;검색할 컬러 이외의 다른 컬러 찾기 (*Except 옵션)
      PixelSearch, sx,sy, curx,cury,endx,cury, searchColor,, *Except *TargetFile<%searchFile%>
      if !ErrorLevel
        curx := sx
      else
        break
    }
    else
      break
  }
  ++cury
}

 

;검색된 좌표목록 출력
text = 픽셀서치로 특정컬러블럭의 좌표 찾기 (여기서는 '적색' 블럭)`n`n
for k, v in result
  text .= k " : " v.x "," v.y "`n"
MsgBox,,, % text



Posted by 와이로

ImageCompare 명령어는 크기가 같은 두 이미지를 비교하는 명령어 입니다.

또한 이미지 비교값을 별도의 비트맵으로 출력 할 수도 있습니다.



ImageCompare , hBitmap1, hBitmap2, [hResultVar], [option]

 

[결과값]

ErrorLevel = 0 : 이미지동일

ErrorLevel = 1 : 이미지다름

ErrorLevel = 2 : 이미지오류 (이미지가 준비되지 않았거나 이미지 크기가 다를때 발생)

 

[옵션]

*HBmp1NotDel, *HBmp2NotDel : 기본적으로 hBitmap1, hBitmap2 는 명령어 수행 후 비트맵 핸들이 소멸하지만, 이 옵션들을 사용 할 경우 핸들이 유지 됩니다.

이 옵션들을 사용 할 시 차후에 비트맵 핸들을 해제해 주어야 합니다. 

-> ex) DllCall("DeleteObject", Ptr,hBitmap)

*NN : 비교 공차값, NN=0~255

 

 

이미지 비교 방법을 보기 위해 제가 가끔 하는 게임에서 테스트한 이미지를 예로 들겠습니다.

이미지 캡춰는 ImageGet 명령어를 사용했습니다.
 

1. 이미지1


2. 이미지2   -  이미지1 캡춰 후 0.2초 후 캡춰 (그냥 보면 이미지1과 다를게 없어 보입니다)


3. 비교결과 이미지

비교값이 같으면 검은색 다르면 흰색 입니다.

몬스터같은 경우는 끊임없이 움직이므로 항상 흰색으로 나타납니다.

그외 초목이나 구름의 이동 같은 경우도 흰색으로 나타납니다만 몬스터위치처럼 완전히 흰색으로 뭉쳐 있지는 않습니다.


4. 비교결과 이미지 보정

이미지 비교시 비교오차를 미적용시 대상이미지(여기서는 큰곰) 내에 검은색 잡티가 발생합니다. 이를 제거하기 위한 과정입니다.



 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

이미지비교_샘플.zip

 

<스크립트 샘플>


imgFile1 := "1.이미지1.bmp"

imgFile2 := "2.이미지2.bmp"

잡티픽셀크기 := 2


;액티브 윈도우의 지정영역 시간차 캡쳐 후 비교

F1::

  CoordMode, Pixel, Relative

  ImageGet, hBmp1, 9,163,631,318,, *WH

  sleep, 200

  ImageGet, hBmp2, 9,163,631,318,, *WH

  SaveHBITMAPToFile(hBmp1, imgFile1)

  SaveHBITMAPToFile(hBmp2, imgFile2)

  

  ;두 이미지 비교값을 hBmpResult 로 출력

  ImageCompare, hBmp1, hBmp2, hBmpResult

  cmpErrorLevel := ErrorLevel

  SaveHBITMAPToFile(hBmpResult, "3.비교값.bmp")


  ;두 이미지 비교값을 보정 - 잡티 제거

  ImageFilter, BoundaryClean, hBmpResult, hBmpResult,,,,, *SearchColorBlack *FillColorWhite *SizeMax%잡티픽셀크기%

  SaveHBITMAPToFile(hBmpResult, "4.비교값보정.bmp")


  msg =

  (LTrim

    ErrorLevel = %cmpErrorLevel%

  

    0 = 비교값 같음

    1 = 비교값 다름

    2 = 이미지 오류, 비교용 이미지 크기가 서로 달라도 이 오류가 뜸니다.

  )

  MsgBox % msg

  

  DllCall("DeleteObject", Ptr,hBmpResult)

return

 

 

 

Posted by 와이로

CursorMatchTest  명령어는 현재 마우스커서와 이미지파일속 커서를 비교하는 명령어입니다. 매치테스트 성공 및 실패 여부는 ErrorLevel 값으로 알수 있습니다.



CursorMatchTest , ImageFile, [option]

 

[결과값]

ErrorLevel = 0 : 마우스 커서와 동일 이미지

ErrorLevel = 1 : 마우스 커서와 다른 이미지

 

[옵션]

*HBmp : ImageFile 대신 HBITMAP 핸들값을 사용할 경우의 옵션입니다. (명령어 사용 후 핸들값 자동 초기화)

*HBmpNotDel : *HBmp 옵션과 같지만 명령어 사용 후 핸들값이 초기화 되지 않습니다.

  사용이 끝난 핸들값은 "DllCall("DeleteObject", Ptr,hBitmap)" 함수로 초기화 해주세요.

 

마우스 커서 캡춰는 ImageGet, hBitmap,,,,,, *CursorOnly 명령어를 사용하면 됩니다.

 


 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

마우스커서_비교.zip

 

 

<샘플 스크립트>

 

F1::   ;현재 커서 캡춰
  ImageGet, hBitmap,,,,,, *CursorOnly
  SaveHBITMAPToFile(hBitmap, "mouse_cursor.bmp")
  DllCall("DeleteObject", hBitmap)
  ToolTip, 현재커서 캡춰완료
return

 

F2::   ;캡춰된 커서와 현재 커서 비교

  CursorMatchTest, mouse_cursor.bmp
  ToolTip, % ErrorLevel? "불일치" : "일치"
return

 

Posted by 와이로

ColorReplace 명령어는 비트맵의 특정색상을 모두 교체하거나

특정색상을 제외한 다른 모든색을 교체 하는데 사용합니다.

ImageSearch 명령어와 병용해서 사용하면 효과적인 코딩이 가능합니다.



ColorReplace , hNewBmpVar, hOrgBmp, searchColor, replaceColor [, option]

 

[결과값]

ErrorLevel = 0 : 명령어 정상 실행

ErrorLevel = 1 : 명령어 실행 오류


[변수]

searchColor : 찾아야 할 컬러값(여러개의 컬러일 경우 '|' 기호로 구분)

replaceColor : 교체할 컬러값


[옵션]
*BGR : BGR 컬러를 사용할때 쓰는 옵션이며, 이 옵션이 없을시 RGB 로 적용 됩니다.
*Except : searchColor 값을 제외한 모든 컬러값을 교체합니다.
*SrcNotDel : hOrgBmp 핸들을 초기화 하지 않습니다. 이 옵션이 없을시엔 초기화 됩니다.
*n(variation) : 0~255사이의 숫자값으로 searchColor 값에 공차값을 적용합니다.

 

주의 1) hOrgBmp가 DC에서 사용중인 경우 DC에서 선택해제 후에 사용해야 합니다.

주의 2) 반환되는 hNewBmpVar 핸들은 사용이 끝날시 꼭 초기화 시켜줘야 합니다.

 ->ex) DllCall("DeleteObject", Ptr,hNewBmpVar)
 



 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

컬러리플레이스_샘플.zip

 

 

사용예)

 

bmpFile = 0.원본비트맵.bmp
ImageGet, hBitmapOrg,,,,, bmpFile


cRed := 0xED1C24
cBlack := 0x000000
cBlue := 0x00A2E8


;빨강색 -> 검정색

;*SrcNotDel 옵션시 hBitmapOrg 핸들값은 ColorReplace 명령후에도 유지된다.
ColorReplace, hBitmap, hBitmapOrg, cRed, cBlack, *SrcNotDel  

SaveHBITMAPToFile(hBitmap, "1.빨강색-검정색.bmp")
DllCall("DeleteObject", Ptr,hBitmap)

 

;검정색 -> 빨강색
ColorReplace, hBitmap, hBitmapOrg, cBlack, cRed, *SrcNotDel
SaveHBITMAPToFile(hBitmap, "2.검정색-빨강색.bmp")
DllCall("DeleteObject", Ptr,hBitmap)

 

;빨강색을 제외한 모든색상 파랑색으로 교체
ColorReplace, hBitmap, hBitmapOrg, cRed, cBlue, *SrcNotDel *Except
SaveHBITMAPToFile(hBitmap, "3.빨강색제외-파랑색.bmp")
DllCall("DeleteObject", Ptr,hBitmap)

 

;검정색을 제외한 모든색상 파랑색으로 교체
ColorReplace, hBitmap, hBitmapOrg, cBlack, cBlue, *SrcNotDel *Except
SaveHBITMAPToFile(hBitmap, "4.검은색제외-파랑색.bmp")
DllCall("DeleteObject", Ptr,hBitmap)

 

;사용이 끝난 hBitmapOrg 비트맵 해제
DllCall("DeleteObject", Ptr,hBitmapOrg)

 

 

0. 원본비트맵

 

 

1. 빨강->검정                 2.검정->빨강       

 

 

 

 

3.빨강제외->파랑         4.검정제외->파랑

 

 



Posted by 와이로

스크린샷 또는 마우스커서 이미지를 얻거나 파일에서 이미지를 로딩하는 명령어를 추가해 봤습니다.

그냥 DllCall 명령어로 만들어 쓸수 있지만 간편하게 써보려고 만들어 봤습니다. 



ImageGet , hBitmapOutVar, [X1, Y1, X2, Y2, InputVar, *option, OutputVarObj]

 

[결과값]

ErrorLevel = 0 : 명령어 정상 실행

ErrorLevel = 1 : 명령어 실행 오류

 

[변수]

hBitmapOutVar : 캡춰되거나 파일에서 로딩한 비트맵데이터의 핸들이 저장되는 변수입니다.

(주의) 사용이 끝난 비트맵핸들의 초기화 필수 - DllCall("DeleteObject", Ptr,hBitmap)

InputVar : 파일에서 로딩하는경우 파일경로나 파일명이 저장된 변수입니다.

      - 변수설정을 하지 않거나 변수에 설정된 값이 없는 경우 CoordMode, Pixel 설정에 따라 윈도우 또는 전체화면 캡쳐를 수행합니다.

OutputVarObj : 해당변수가 존재할시 hBitmapOutVar 출력 이미지의 {width, height} 값을 얻을수 있습니다.

 

[옵션]

*WH : X2, Y2를 가로 세로값(픽셀수)으로 사용합니다.

*CursorOnly : 커서이미지를 가져옵니다.

*ClearBack : 윈도우 캡춰시 뒤쪽 윈도우 잔상현상이 나타날시 사용하는 옵션입니다.

      - CoordMode, Pixel, Relative( or Client) 모드 전용(전체화면 캡춰시엔 필요없는 옵션)

*HBmp : InputVar 변수 값이 HBITMAP 핸들임을 나타내며 명령어 사용후 자동으로 핸들 초기화됩니다.

*HBmpNotDel : InputVar 변수 값이 HBITMAP 핸들임을 나타내며 명령어 사용후에도 핸들이 유지됩니다.

*MemFile : 변수에 저장된 파일구조의 이미지를 비트맵으로 전환할때 사용합니다.

- 현재는 비트맵 파일과 adb에서 받아온 raw이미지 형태의 파일만 가능합니다.

- 로딩된 비트맵 파일구조에서 비트맵을 얻는 오토핫키 스크립트도 있으니 참고하세요.

*HWnd : 지정윈도우 캡쳐시 사용되며 InputVar 변수에 저장된 값을 HWND 핸들로 인식합니다.

*PrintWindow : 지정윈도우 캡쳐시 비활성 캡쳐가 가능하도록 합니다.

- AeroPeek 기능이 활성화된 상태여야 합니다.

- OpenGL 사용 윈도우의 경우 Win10 미만의 버전에서는 캡쳐가 되지 않을 수 있습니다.

*Channel[R|G|B] : 이미지의 RGB 채널을 선택할 수 있습니다. (ex. *ChannelR, *ChannelRB)

 



Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

ImageGet_명령어.zip



사용예)

 

;액트브 윈도우 전체스샷

CoordMode, Pixel, Relative

ImageGet, hBitmap

SaveHBITMAPToFile(hBitmap, "1.액티브윈도우_전체.bmp")

DllCall("DeleteObject", Ptr,hBitmap)

;액티브 윈도우의 클라이언트 전체스샷

CoordMode, Pixel, Client

ImageGet, hBitmap

SaveHBITMAPToFile(hBitmap, "2.액티브윈도우_클라이언트영역.bmp")

DllCall("DeleteObject", Ptr,hBitmap)

;풀스크린샷

CoordMode, Pixel, Screen

ImageGet, hBitmap

SaveHBITMAPToFile(hBitmap, "3.스크린_전체.bmp")

DllCall("DeleteObject", Ptr,hBitmap)

;액티브윈도우의 선택영역 스크린샷

CoordMode, Pixel, Relative

ImageGet, hBitmap, 0,0,80,120

SaveHBITMAPToFile(hBitmap, "4.액티브윈도우_지정영역.bmp")

DllCall("DeleteObject", Ptr,hBitmap)


;마우스가 위치한 특정 윈도우의 클라이언트 영역 스크린샷

MouseGetPos,,, hwnd

CoordMode, Pixel, Client

ImageGet, hBitmap, 0,0,0,0, hwnd, *HWnd *PrintWindow

SaveHBITMAPToFile(hBitmap, "5.지정윈도우_클라이언트영역.bmp")

DllCall("DeleteObject", Ptr,hBitmap)


;커서 이미지 가져오기

ImageGet, hBitmap,,,,,, *CursorOnly

SaveHBITMAPToFile(hBitmap, "6.마우스커서.bmp")

DllCall("DeleteObject", Ptr,hBitmap)

;이미지 파일의 특정영역만 가져오기

imageFile = sample_image.bmp

ImageGet, hBitmap, 200, 150, 50, 30, imageFile, *WH, imageObj

SaveHBITMAPToFile(hBitmap, "7.sample_image_x200y150w50h30영역.bmp")

DllCall("DeleteObject", Ptr,hBitmap)

MsgBox % "파일에서 읽어온 이미지 크기 = " imageObj.width "x" imageObj.height


 


 

 

*ClearBack 옵션 사용 예

 

이런 배치에서 블루스택 윈도우를...

 

 

아래 스크립으로 캡춰할 경우 뒤에 있는 윈도우 영향으로 잔상 또는 크랙 현상이 발생합니다.

(특정 윈도우환경에서만 나타날 수 있는 현상으로 일반적인 현상은 아닙니다.)

F1::

  CoordMode, Pixel, Relative
  ImageGet, hBitmap
  SaveHBITMAPToFile(hBitmap, "1.bmp")
  DllCall("DeleteObject", Ptr,hBitmap)

  ;SaveHBITMAPToFile() 함수는 첨부파일 스크립트에 있으므로 복사해서 테스트 하세요.

return

 

 

이런 경우 *ClearBack 옵션을 써주면 아래처럼 깔끔한 캡춰가 가능합니다.

단 명령어 수행속도가 대폭 느려지므로 깨짐현상이 발생하는 경우에만 사용을 권합니다.

F1::

  CoordMode, Pixel, Relative
  ImageGet, hBitmap,,,,,, *ClearBack
  SaveHBITMAPToFile(hBitmap, "2.bmp")
  DllCall("DeleteObject", Ptr,hBitmap)

  ;SaveHBITMAPToFile() 함수는 첨부파일 스크립트에 있으므로 복사해서 테스트 하세요.

return

 

 

 

Posted by 와이로

이 프로그램은 대항해시대 온라인 다중클라이언트를 사용하는 플레이어들의 대항해시대 윈도우 전환을 쉽게 할수 있도록 보조합니다. 오토핫키로 제작됬으며 스크립트가 포함되 있으므로 마음대로 수정해서 사용하셔도 됩니다.

 

이 프로그램은 게임 클라이언트에 어떠한 핸들링도 가하지 않으며 오직 대항해시대 온라인 클라이언트를 시작줄에서 올리고 내리거나 윈도우 위치를 옮기는 역활만 수행하므로 게임사의 약관에 위배되는 일을 하지 않습니다.

 

추신) 게임을 접은지 오래되서 대규모 업데이트로 인해 화면인식지점의 이미지가 바껴 오동작이 있을 수 있습니다. 추후 게임을 다시 하게 된다면 그때 체크해 보도록 하겠습니다.


대항온윈도우전환기.zip

대항온 유저들이 핵에 민감해서 실행파일 없이 소스파일만 올립니다. 직접 오토핫키 컴파일러로 컴파일해서 exe 파일 만들어 쓰시거나 오토핫키 설치 후 그냥 ahk 파일 더블클릭으로 실행하시면 됩니다.


글로벌 서버에서 사용하시려면 대항온윈도우전환기.ahk 파일을 메모장으로 열어 아래 항목을 수정 후 저장해 주시면 됩니다.

mainTitle = Uncharted Waters Online 

 



'게임 도우미' 카테고리의 다른 글

대항온 윈도우 전환기(스크립트)  (8) 2015.09.05
Posted by 와이로

픽셀피커 많이들 있는데 이건 제가 자작해서 쓰는 피커 입니다.

사용 라이브러리는 GDI class 입니다.

 

업데이트를 하지않아 손볼곳이 좀 있으나 크게 불편하지 않아 그냥 쓰고 있습니다.

제가 좀 게으름니다 ㄷㄷ

 

주요 기능을 살펴 보겠습니다.

1. F1 키로 마우스영역 픽셀업데이트를 홀드 및 언홀드 시킬수 있습니다.

2. RGB GRB 토글이 가능합니다.

3. 가드가 보호하는 게임에서 컬러 추출 안될시 AntiGuird를 체크하면 추출이 가능합니다.

4. F2 키로 콤보박스의 픽셀추출 포멧을 이용해 Ctrl 클릭으로 다중 선택된 픽셀을 일괄 추출 가능합니다. 포멧은 ini 파일을 이용해 마음대로 수정 및 추가 가능합니다.

 

주의할점은 제어판-시각효과 설정중 에어로피크나 바탕화면구성등이 설정되 있으면 갱신속도가 엄청나게 느려질 수 있습니다.

 

= 포멧사용 샘플 =

 

포멧1 : [%x%,%y%] %colormode% %color%
[5,7] GRB 0x123168
[6,5] GRB 0x0B215F
[6,7] GRB 0x071C55

 

포멧2 : [%x%,%y%] %delimiter%,%%
[5,7],[6,5],[6,7]

 

포멧3 : {x:%x%,y:%y%} %delimiter%,%%
{x:5,y:7},{x:6,y:5},{x:6,y:7}

 

  PixelPicker.zip

 

 

 

 

 

 

 

 

 

 

'유틸리티' 카테고리의 다른 글

[Ahk+] 오토핫키+ 명령어 적용된 AutoHotkey.exe  (1) 2015.10.07
Pixel Color Picker(스크립트)  (2) 2015.09.05
Posted by 와이로

이미지서치의 기능을 확장시켰습니다.

 

 

ImageSearch , OutputVarX, OutputVarY, X1, Y1, X2, Y2, [*option] ImageFile, [OutputVarObj]

 

[*option]

*WH : X2, Y2를 가로 세로값(픽셀수)으로 사용

*IconN : 기존옵션 - 아이콘 그룹선택

*n(variantion) : 기존옵션 - 컬러공차값

 

*Scan(RB|BR|LT|TL|RT|TR|LB|BL) : 이미지서치시 스캔방향 설정 옵션


*Result(LT|LB|RT|RB|Center|Random)

  이미지서치 성공시 반환되는 좌표값을 검색한 이미지 크기를 기준으로 받아올수 있습니다.  보통은 검색된 이미지의 좌측상단 좌표를 받지만 중간좌표나 랜덤좌표를 받을수 있게 설정할수도 있습니다.

 

*TransN : 기존옵션


*TransnotN : 검색하는 이미지의 TransN컬러값부분에 TransnotN으로 설정한 컬러값이 있을경우 부합하지 않도록 합니다.

  이 옵션은 규격화된 글자이미지나 숫자 이미지 검색시 겹치는 픽셀이 있는 이미지가 있을경우 사용합니다.  예를 들어 숫자3 과 숫자8을 이미지서치 한다고 했을때 숫자3 이미지로 검색하는 경우 숫자8도 검출이 됩니다.  검색용 이미지의 배경이 흰색이고 글자색이 검은색이라고 했을시 TransWhite 값과 TransnotBlack으로 설정하면  숫자3이미지로 숫자8이미지 위치를 검색 할 때 숫자3의 모든 흰색배경픽셀과 매칭되는 검색대상 픽셀에 검은색 이 있을경우 노매칭으로 판단하게 됩니다. 이렇게 숫자3 이미지로 검색할때 숫자8이 검색되는 현상을 막을수 있습니다.


*HBmp : 검색이미지를 이미지파일 대신 HBITMAP 핸들을 사용하게 하는 옵션

     (참고) v1.1.23.00 버전에서 이 옵션과 동일한 기능인 hbitmap: 옵션이 추가되었네요.

*HBmpNotDel : HBmp 옵션과 같지만 사용한 핸들이 자동 소멸하지 않도록 해주는 옵션

(주의) *HBmp와 *HBmpNotDel 옵션을 지정할시 검색소스이미지파일명 자리에 HBITMAP 핸들값을 넣어주어야 하며 *W 및 *H 옵션을 설정하더라도 적용되지 않습니다.(추후 패치 예정)


*All , *Allnn : 동일이미지를 검색영역에서 모두 검색되며 검색된 모든 좌표값은 OutputVarObj 변수를 통해 배열로 반환됨, Allnn인 경우는 해당 nn 개수 까지만 검색


*Target(File|HBmp|HBmpNotDel)xx : 이미지서치 대상을 화면이 아닌 이미지파일이나 HBITMAP 핸들로 지정합니다.

(주의) *TargetFile 옵션을 사용할시 <> 기호로 파일경로를 둘러싸 주어야 합니다.

ex) *TargetFile<C:\image.bmp>

 

[OutputVarObj]

  OutputVarX, OutputVarY 변수로 받는 검색좌표 값 외에  옵션에 따라 반환값이 추가되는 경우 이 오브젝트변수로 받을 수 있습니다.

*All 옵션 없을때 오브젝트변수가 있는 경우 오브젝트에 저장되는 값

  - Object{validx, validy, validw, validh, w, h}

*All 옵션 있을때 오브젝트변수가 있는 경우 오브젝트 리스트에 저장되는 값

  - Object[number]{x, y}  (number 값은 1부터 시작하는 순차배열 번호)
  - Object{count, w, h, validox, validoy, validw, validh} 

    (validox 및 validoy 값은 유효영역 오프셋값)

 

여기서 validx, validy, validw, validh 값은 *Trans 옵션이 있을시 트랜스컬러영역을 최대한 걷어낸 유효한 이미지 영역입니다.

 


 

*Scan 옵션에 대한 세부설명

이미지서치나 픽셀서치에서 *ScanXX 옵션으로 설정 가능하며 검색시작점과 검색방향의 우선순위를 지정하는데 사용합니다. 오토핫키의 기본 스캔방향은 왼쪽상단에서 오른쪽으로 그리고 아래로 진행하는 방식이며 *ScanRB 옵션과 같습니다.

 

아래 스샷에서 스캔 진행방향은 1번이 선두 스캔방향이며 2번이 후순위 스캔방향입니다.

 

 


 

*Result 옵션에 대한 세부설명

 

*Result 옵션은 아래 그림의 파란색 영역을 이미지서치로 찾았을 시 반환되는 좌표를 결정하는 옵션입니다. 이 옵션이 없을 경우 기본 설정으로 검색성공한 위치의 LT(Left Top) 좌표를 반환합니다. 아래 그림에 없는 옵션인 Random 옵션은 검색성공한 파란색 영역 내의 랜덤좌표를 반환합니다.

 

 


 


 

Test.ahk 파일을 다운로드한  'Ahk+ 전용 AutoHotkey.exe 파일'  위에 드래그해서 실행하세요.

ImageSearch_NewOption.zip

 


 

ImageSearch 추가 예문 -> ImageSearch 예문1 - 동영상에서 이미지 찾기


ImageSearch 다중 이미지서치 예문 -> [Ahk+] 이미지 멀티서치 예문

Posted by 와이로