Jump to content

PixelGetColor Performance


Recommended Posts

If I run a loop through the pixels in my screen it was incredibly slow - I was moving the mouse cursor to each position in the loop and discovered that was slowing it down alot.

However even with the MouseMove functions taken out it's still pretty slow.

I want to ultimately scan for images or parts of images on the screen.

Can anyone suggest why or a better way to do this kind of thing ?

Link to comment
Share on other sites

Imagine if you had an 8x8 pixel image consisting of known colors. If you scan pixel 1x1 and it does not match the known color then you don't need to scan the rest of the pixels. Simply jump to pixel 9x9 and scan it for a match.

Link to comment
Share on other sites

about the pixel info you can get the 0Scan of a bitmap object and sorting it in an array, i made this a time ago, it`s a little bugged but you can get an idea.

(Check the output console for the times that it takes every function)

All the credits to those who appear in the comments

#include <misc.au3>
    #include <WindowsConstants.au3>
    #include <winapi.au3>
    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    #include <ScreenCapture.au3>
    HotKeySet("{esc}", "_exit")
    Global $pos
    $Gui = GUICreate("selection tool", 300, 50, -1, -1)
    $bnSelect = GUICtrlCreateButton("start select", 0, 0, 100, 50)
    $bnShowRaw = GUICtrlCreateButton("ShowRawData", 100, 0, 100, 50)
    GUICtrlSetState($bnShowRaw, $GUI_DISABLE)
    $bnShowFromRD = GUICtrlCreateButton("ShowScrenfromRD", 200, 0, 100, 50)
    GUICtrlSetState($bnShowFromRD, $GUI_DISABLE)
    GUISetState()
    While 1
       $nmsg = GUIGetMsg()
       Switch $nmsg
          Case -3
             _exit()
          Case $bnSelect
             $sel = _drawbox()
             If IsArray($sel) Then
                GUICtrlSetState($bnShowRaw, $GUI_ENABLE)
             EndIf
          Case $bnShowRaw
             $begin1 = TimerInit()
             $rawdata = _Getrawdata($sel[4])
             If Not @error Then
                ConsoleWrite("Time in ms to do all the work = " & TimerDiff($begin1) & @CRLF)
                GUICtrlSetState($bnShowFromRD, $GUI_ENABLE)
                                    _arraydisplay($rawdata)
             EndIf
          Case $bnShowFromRD
             $ShowGUI = GUICreate("screen show", $sel[2], $sel[3], $sel[0], $sel[1], $WS_POPUP)
             $graph = GUICtrlCreateGraphic(0, 0, $sel[2], $sel[3])
             _printrawdata($rawdata, $graph)
             GUISetState(@SW_SHOW, $ShowGUI)
             GUICtrlSetState($graph, $GUI_SHOW)
             MsgBox(0, "tip", "Press ´BackSpace´key to close Show window")
             Do
                Sleep(50)
             Until _IsPressed("08") ; BackSpace
             GUIDelete($ShowGUI)
       EndSwitch
    WEnd
    Func _Exit()
       Exit
    EndFunc   ;==>_Exit
    Func _drawbox() ; Credits to Melba23
       $hGui = GUICreate("selectionbox", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
       GUISetBkColor(0x000000, $hGui)
       WinSetTrans($hGui, "", 20)
       GUISetState()
       GUISetCursor(3)
       $DLL = DllOpen("user32.dll")
       While Not _IsPressed("01", $DLL)
          $pos = MouseGetPos()
          Sleep(10)
       WEnd
       $iX = $pos[0]
       $iW = 0
       $iY = $pos[1]
       $iH = 0
       While _IsPressed(01, $DLL)
          $pos2 = MouseGetPos()
          Select
             Case $pos2[0] < $pos[0]
                $iX = $pos2[0]
                $iW = $pos[0] - $pos2[0]
             Case $pos[0] < $pos2[0]
                $iX = $pos[0]
                $iW = $pos2[0] - $pos[0]
          EndSelect
          Select
             Case $pos2[1] < $pos[1]
                $iY = $pos2[1]
                $iH = $pos[1] - $pos2[1]
             Case $pos[1] < $pos2[1]
                $iY = $pos[1]
                $iH = $pos2[1] - $pos[1]
          EndSelect
          _GUICreateInvRect($hGui, $iX, $iY, $iW, $iH)
       WEnd
       GUIDelete($hGui)
       DllClose($DLL)
       $begin = TimerInit()
       $hBMP = _ScreenCapture_Capture("", $iX, $iY, $iW + $iX, $iH + $iY)
       ConsoleWrite("Time in ms. to take a screen from a " & $iW & "X" & $iH & " Area = " & TimerDiff($begin) & @CRLF)
       Local $selectedpos[5] = [$iX, $iY, $iW, $iH, $hBMP]
       Return $selectedpos
    EndFunc   ;==>_drawbox

    Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)
       $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
       $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
       $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
       $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)
       _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
       _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
       _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)
       _WinAPI_DeleteObject($hMask_2)
       _WinAPI_DeleteObject($hMask_3)
       _WinAPI_DeleteObject($hMask_4)
       _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)
    EndFunc   ;==>_GUICreateInvRect
    Func _Getrawdata($hBMP) ; Credits to Malkey http://www.autoitscript.com/forum/index.php?app=forums&module=forums&section=findpost&pid=718522
       _GDIPlus_Startup()
       $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
       $width = _GDIPlus_ImageGetWidth($hBitmap)
       $height = _GDIPlus_ImageGetHeight($hBitmap)
       Local $aSize = DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBMP, 'int', 0, 'ptr', 0)
       If Not @error Then
          $tBits = DllStructCreate('byte[' & $aSize[0] & ']')
          $begin = TimerInit()
          DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBMP, 'int', $aSize[0], 'ptr', DllStructGetPtr($tBits))
          $sHex = Hex(DllStructGetData($tBits, 1))
          ConsoleWrite("Time in ms. to get the rawdata and save it in a variable = " & TimerDiff($begin) & @CRLF)
          $begin = TimerInit()
          $sHex = StringRegExpReplace($sHex, "([[:xdigit:]]{6})(FF)", "\1 ")
          Local $pix[$height][$width], $aTemp
          $aArr = StringRegExp($sHex, "(.{" & ($width * 7) & "})", 3)
          ConsoleWrite("Time in ms to preparate the rawdata to be indexed in an array = " & TimerDiff($begin) & @CRLF)
          $begin = TimerInit()
          For $width = 0 To UBound($aArr) - 1
             $aTemp = StringRegExp($aArr[$width] & " ", "(.{6}) ", 3)
             For $height = 0 To UBound($aTemp) - 1
                $pix[$width][$height] = StringRegExpReplace($aTemp[$height], "(.{2})(.{2})(.{2})", "\3\2\1") ; To RGB format
             Next
          Next
          ConsoleWrite("Time in ms to put the entire raw in an array = " & TimerDiff($begin) & @CRLF)
       Else
          SetError(@error)
          Return ""
       EndIf
       _GDIPlus_BitmapDispose($hBitmap)
       _WinAPI_DeleteObject($hBMP)
       _GDIPlus_Shutdown()
       Return $pix
    EndFunc   ;==>_Getrawdata
    Func _printrawdata($ArBMPRawdata, $hgraphic)
       $begin = TimerInit()
       For $x = 0 To UBound($ArBMPRawdata) - 1
          For $y = 0 To UBound($ArBMPRawdata, 2) - 1
             $color = "0x" & $ArBMPRawdata[$x][$y]
             GUICtrlSetGraphic($hgraphic, $GUI_GR_COLOR, $color)
             GUICtrlSetGraphic($hgraphic, $GUI_GR_PIXEL, $y, $x) ; :S
             GUICtrlSetState($graph, $GUI_SHOW)
          Next
       Next
       ConsoleWrite("Time in ms to print from the rawdata using GuictrlsetGraphics = " & TimerDiff($begin) & @CRLF)
    EndFunc   ;==>_printrawdata
Edited by monoscout999
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...