Grisgram Posted February 21, 2008 Share Posted February 21, 2008 (edited) Hi, I just wrote a little Utility in AutoIt which allows you to capture a screen region from a running application and get the PixelChecksum for that region so you can use the value later in your code to compare it. Just start the script, enter the dimensions of the area to capture and click the "Capture" Button. Then activate the window to capture and move the mouse to the point (top left corner) where you want to capture and press your hotkey. The script will then capture that area, calculate the PixelChecksum and display it in a Textbox so you can copy it to your script. The coordinates where you captured (in the client area of that window) will also be displayed. I found it quite useful to automate some browser applications when it came to detect which kind of message or image is displayed in a specific area. Here's the script, enjoy it and please let me know any enhancements you build into it or bugs you find. cheers, expandcollapse popup#include <GUIConstants.au3> #include <ScreenCapture.au3> Opt("GUIOnEventMode", 1); Change to OnEvent mode Opt("PixelCoordMode", 1); Screen coordinates Opt("MouseCoordMode", 1); Screen coordinates ; ----------------------------------------------------------------------- ; --- M A I N P R O G R A M --- I N I T I A L I Z A T I O N ; ----------------------------------------------------------------------- ; Create the main window $mainwindow = GUICreate("AutoIt CheckSummer", 640, 400) GUISetOnEvent($GUI_EVENT_CLOSE, "frm_Close") ; Create the picture box to hold the capture GUICtrlCreateLabel("Captured image:", 240, 69) $pic = GUICtrlCreateGraphic(240, 90, 256, 256) GUICtrlSetBkColor($pic, 0xffffff) GUICtrlCreateLabel("Captured image pixel checksum:", 240, 353) $checksum = GUICtrlCreateEdit("0", 400, 350, 96, 20, $ES_NUMBER) GUICtrlCreateLabel("Captured at mouse position:", 240, 370) $capturepos = GUICtrlCreateLabel(" ", 400, 370) GUICtrlCreateLabel("This tool is used to capture a portion of an image and get the PixelChecksum for it.", 10, 10) GUICtrlCreateLabel("Set the capture dimension in the textboxes then activate target window and move the mouse to the capture point.", 10, 24) GUICtrlCreateLabel("The maximum image size to be captured for checksum is 256x256 pixels.", 10, 38) GUICtrlCreateLabel("Width:", 10, 75) GUICtrlCreateLabel("Height:", 10, 99) $txtWidth = GUICtrlCreateEdit("32", 50, 72, 60, 20, $ES_NUMBER) $txtHeight = GUICtrlCreateEdit("32", 50, 96, 60, 20, $ES_NUMBER) $cmdCapture = GUICtrlCreateButton("Capture!", 35, 120, 90) GUICtrlSetOnEvent($cmdCapture, "CaptureNow") GUICtrlCreateLabel("Hotkey:", 10, 163) $txtHotkey = GUICtrlCreateEdit("c", 50, 160, 60, 20) GUICtrlCreateLabel("Press the hotkey when the mouse is", 10, 190) GUICtrlCreateLabel("positioned at the capture point.", 10, 204) GUICtrlCreateLabel("You can enter any custom hotkey here.", 10, 218) GUICtrlCreateLabel("Modifier help:", 10, 240) GUICtrlCreateLabel("^ ... Control", 10, 254) GUICtrlCreateLabel("! ... Alt", 10, 268) GUICtrlCreateLabel("+ ... Shift", 10, 282) GUICtrlCreateLabel("# ... Windows key", 10, 296) GUISwitch($mainwindow) GUISetState(@SW_SHOW) $lastimg = 0 ; Idle loop While 1 Sleep(1000) WEnd ; ----------------------------------------------------------------------- ; --- E V E N T M E T H O D S - $mainwindow ; ----------------------------------------------------------------------- Func frm_Close() If @GUI_WINHANDLE = $mainwindow Then Exit EndFunc ; ----------------------------------------------------------------------- ; --- E V E N T M E T H O D S - $cmdCapture ; ----------------------------------------------------------------------- Func CaptureNow() $wi = GUICtrlRead($txtWidth) $he = GUICtrlRead($txtHeight) if ($wi < 1 or $wi > 256 or $he < 1 or $he > 256) Then MsgBox(0, "Dimension error", "Width and Height must be between 1 and 256 (both including)!") Return EndIf HotKeySet(GUICtrlRead($txtHotkey), "CaptureKeyPressed") EndFunc Func CaptureKeyPressed() Opt("PixelCoordMode", 1); Screen coordinates Opt("MouseCoordMode", 1); Screen coordinates $mouse = MouseGetPos() $wi = GUICtrlRead($txtWidth) $he = GUICtrlRead($txtHeight) _ScreenCapture_Capture(@TempDir & "\capture.bmp", $mouse[0], $mouse[1], $mouse[0] + $wi, $mouse[1] + $he, False) ; Get the mouse pos where the capture happened (in the client area of the active form) Opt("PixelCoordMode", 2); Client area of active window Opt("MouseCoordMode", 2); Client area of active window $winmouse = MouseGetPos() ;Beep(1000, 50) Sleep(1000) WinActivate("AutoIt CheckSummer") WinWaitActive("AutoIt CheckSummer") GUICtrlSetData($capturepos, $winmouse[0] & " . " & $winmouse[1]) if $lastimg <> 0 Then GUICtrlDelete($lastimg) $lastimg = GUICtrlCreatePic(@TempDir & "\capture.bmp", 240, 90, $wi, $he) GUICtrlSetData($checksum, PixelChecksum(240, 90, 240 + $wi - 1, 90 + $he - 1, 1)) EndFunc Edited February 21, 2008 by Grisgram Link to comment Share on other sites More sharing options...
junkew Posted March 5, 2008 Share Posted March 5, 2008 Great code.I enhanced the tool in the following areas* Added a small window with transparency that follows the cursor* Added some hotkeys ctrl up,down, left, right to make the window capture area more relative from mouseposition to circumvent highlighting of buttons when you hover over them (actually then the color of the button changes)* Added a find button with a straight forward search algorithm (slow but working). To test try something in upper corner of your screen not in the left bottom unless you have a long time available** Optimizations have to be done to search within a window instead over whole desktop, combine with logic of pixelsearch to limit search area etc.(search in forum on pixelsearch, getpixelcolor)TO DO* Hotkeys to change capture area instead of thru editbox to get exact right dimension easily* Click or whatever when the area is found** Easy for Powerbuilder unrecognizable objects** Easy for difficult to recognize toolbars and other objects that are ownerdrawn* Wrapper function for easier usage* Check if its faster if first an in memory bitmap is made of the whole screen and use bitblt functions to identify corresponding area (Reference: http://www.vbforums.com/showthread.php?t=474786)* Combine with features from http://www.autoitscript.com/forum/index.ph...c=54776&hl=expandcollapse popup#include <GUIConstants.au3> #include <ScreenCapture.au3> Opt("GUIOnEventMode", 1); Change to OnEvent mode Opt("PixelCoordMode", 1); Screen coordinates Opt("MouseCoordMode", 1); Screen coordinates ; ----------------------------------------------------------------------- ; --- M A I N P R O G R A M --- I N I T I A L I Z A T I O N ; ----------------------------------------------------------------------- global $wi, $he, $deltaX, $deltaY;Made global as its shared by other functions $deltax=1 $deltay=1 ; Create the main window $mainwindow = GUICreate("AutoIt CheckSummer", 640, 428) GUISetOnEvent($GUI_EVENT_CLOSE, "frm_Close") GUICtrlCreateLabel("This tool is used to capture a portion of an image and get the PixelChecksum for it.", 10, 10) GUICtrlCreateLabel("Set the capture dimension in the textboxes then activate target window and move the mouse to the capture point.", 10, 24) GUICtrlCreateLabel("The maximum image size to be captured for checksum is 256x256 pixels.", 10, 38) GUICtrlCreateLabel("Ctrl up,down,left,right keys make the capturearea difference from mouse position so highlight of button is not captured.", 10, 52) GUICtrlCreateLabel("Width:", 10, 75) GUICtrlCreateLabel("Height:", 10, 99) $txtWidth = GUICtrlCreateEdit("32", 50, 72, 60, 20, $ES_NUMBER) $txtHeight = GUICtrlCreateEdit("32", 50, 96, 60, 20, $ES_NUMBER) $cmdCapture = GUICtrlCreateButton("Capture!", 35, 120, 90) GUICtrlSetOnEvent($cmdCapture, "CaptureNow") $cmdFind = GUICtrlCreateButton("Find", 135, 120, 90) GUICtrlSetOnEvent($cmdFind, "FindNow") GUICtrlCreateLabel("Hotkey:", 10, 163) $txtHotkey = GUICtrlCreateEdit("c", 50, 160, 60, 20) GUICtrlCreateLabel("Press the hotkey when the mouse is", 10, 190) GUICtrlCreateLabel("positioned at the capture point.", 10, 204) GUICtrlCreateLabel("You can enter any custom hotkey here.", 10, 218) GUICtrlCreateLabel("Modifier help:", 10, 240) GUICtrlCreateLabel("^ ... Control", 10, 254) GUICtrlCreateLabel("! ... Alt", 10, 268) GUICtrlCreateLabel("+ ... Shift", 10, 282) GUICtrlCreateLabel("# ... Windows key", 10, 296) ; Create the picture box to hold the capture GUICtrlCreateLabel("Captured image:", 240, 78) $pic = GUICtrlCreateGraphic(240, 104, 256, 256) GUICtrlSetBkColor($pic, 0xffffff) GUICtrlCreateLabel("Captured image pixel checksum:", 240, 370) $checksum = GUICtrlCreateEdit("0", 400, 370, 96, 20, $ES_NUMBER) GUICtrlCreateLabel("Captured at mouse position:", 240, 394) $capturepos = GUICtrlCreateLabel(" ", 400, 394) GUISwitch($mainwindow) GUISetState(@SW_SHOW) $lastimg = 0 HotKeySet("^{UP}", "onCtrlUp") HotKeySet("^{DOWN}", "onCtrlDown") HotKeySet("^{LEFT}", "onCtrlLeft") HotKeySet("^{RIGHT}", "onCtrlRight") func onCtrlUp() $deltaY=$deltaY+1 EndFunc func onCtrlDown() $deltaY=$deltaY-1 EndFunc func onCtrlRight() $deltaX=$deltaX-1 EndFunc func onCtrlLeft() $deltaX=$deltaX+1 EndFunc func setSnapWindow() Opt("PixelCoordMode", 1); Screen coordinates Opt("MouseCoordMode", 1); Screen coordinates $mouse = MouseGetPos() ; winmove("Snaparea","", $mouse[0]+1,$mouse[1]+1) winmove("Snaparea","", $mouse[0]-$wi-$deltaX,$mouse[1]-$he-$deltaY) EndFunc $snapwindow = GuiCreate("Snaparea",32, 32,-1,-1, BitOR($WS_POPUP,$WS_BORDER), $WS_EX_TOPMOST) WinSetTrans($snapWindow, "", 50) ; Idle loop While 1 Sleep(250) setSnapWindow() WEnd ; ----------------------------------------------------------------------- ; --- E V E N T M E T H O D S - $mainwindow ; ----------------------------------------------------------------------- Func frm_Close() If @GUI_WINHANDLE = $mainwindow Then Exit EndFunc ; ----------------------------------------------------------------------- ; --- E V E N T M E T H O D S - $cmdCapture ; ----------------------------------------------------------------------- Func CaptureNow() GUISwitch($mainwindow) $wi = GUICtrlRead($txtWidth) $he = GUICtrlRead($txtHeight) if ($wi < 1 or $wi > 256 or $he < 1 or $he > 256) Then MsgBox(0, "Dimension error", "Width and Height must be between 1 and 256 (both including)!") Return EndIf ; Show and receive the snaparea window $mouse = MouseGetPos() GUISetState(@SW_SHOW,$SnapWindow) winmove("Snaparea","", $mouse[0]-$wi-$deltaX,$mouse[1]-$he-$deltaY, $wi, $he) GUISwitch($mainwindow) HotKeySet(GUICtrlRead($txtHotkey), "CaptureKeyPressed") EndFunc Func CaptureKeyPressed() GUISetState(@SW_HIDE,$snapwindow) Opt("PixelCoordMode", 1); Screen coordinates Opt("MouseCoordMode", 1); Screen coordinates GUISwitch($mainwindow) $mouse = MouseGetPos() $wi = GUICtrlRead($txtWidth) $he = GUICtrlRead($txtHeight) _ScreenCapture_Capture(@TempDir & "\capture.bmp", $mouse[0] - $wi-$deltaX, $mouse[1]-$he-$deltaY, $mouse[0]-$deltaX, $mouse[1]-$deltaY, False) ; Get the mouse pos where the capture happened (in the client area of the active form) Opt("PixelCoordMode", 2); Client area of active window Opt("MouseCoordMode", 2); Client area of active window $winmouse = MouseGetPos() ;Beep(1000, 50) ; Sleep(1000) WinActivate("AutoIt CheckSummer") WinWaitActive("AutoIt CheckSummer") GUICtrlSetData($capturepos, $winmouse[0] & " . " & $winmouse[1]) if $lastimg <> 0 Then GUICtrlDelete($lastimg) $lastimg = GUICtrlCreatePic(@TempDir & "\capture.bmp", 240, 104, $wi, $he) GUICtrlSetData($checksum, PixelChecksum(240, 104, 240 + $wi - 1, 104 + $he - 1, 1)) GUISetState(@SW_SHOW,$snapwindow) EndFunc func FindNow() $wi = GUICtrlRead($txtWidth) $he = GUICtrlRead($txtHeight) $tCheckSum=GUICtrlRead($checksum) FindCheckSumOnScreen($tCheckSum,$wi,$he) EndFunc func FindCheckSumOnScreen($checkSumOfImage,$iWidth, $iHeight) dim $screen_x=1, $screen_y=1 $begin=TimerInit() Opt("PixelCoordMode", 1); Screen coordinates Opt("MouseCoordMode", 1); Screen coordinates for $screen_y=1 to @DesktopHeight for $screen_x=1 to @DesktopWidth $screenCheckSum=PixelChecksum($screen_x,$screen_y,$screen_x+$iWidth-1, $screen_y+$iHeight-1) if $screenCheckSum=$checkSumOfImage then mousemove($screen_x,$screen_y,0) winmove("Snaparea","", $screen_x,$screen_y) msgbox(0,"Great","Found the picture at " & $screen_x & ":" & $screen_y & "within " & timerdiff($begin) / 1000 & " seconds:") return EndIf Next next EndFunc FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
junkew Posted March 9, 2008 Share Posted March 9, 2008 Combine it with * In memory pixelsearch http://www.autoitscript.com/forum/index.php?showtopic=63318* To drag box dynamically to right size http://www.autoitscript.com/forum/index.ph...amp;hl=mouseset FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now