Jump to content

Pixel Search Question


Recommended Posts

Hey,

I'm new to the forums, but I've been using autoit to automate windows task for a while. I had a few questions about pixel search:

How efficient is it? (how long would it take to scan the entire screen for a specific color?)

I also would like to know about restraining it to a window. I know the nousecoordmode option is used, but do I have to set it to 0 and also use the hwnd parameter? Any clarification would be most helpful.

Link to comment
Share on other sites

Hi and Welcome to the forums!

If Aero (and thus DWM) is enabled you'll have to disable it to get max speed.

I whipped up a quick example:

If _DwmIsEnabled() = True Then
    $Text = "By turning off DWM this script will be much much faster." & @CRLF & "Would you like me to turn off DWM for you??" & @CRLF & "(will be activated again when script end)"
    If MsgBox(4+32+262144, "It seems like you have DWM running.", $Text) = 6 Then _DwmEnable(False)
EndIf

$iTimer = TimerInit()
PixelSearch(0, 0, @DesktopWidth, @DesktopHeight, 0x123456)
ConsoleWrite("Pixelsearch took: " & Round(TimerDiff($iTimer)) & " ms" & @CRLF)

Func _DwmIsEnabled()
    If FileExists(@SystemDir & "\dwmapi.dll") Then
        $Receiver = DllStructCreate("int")
        $aTemp = DllCall("dwmapi.dll", "uint", "DwmIsCompositionEnabled", "ptr", DllStructGetPtr($Receiver, 1))

        $Receiver2 = DllStructCreate("int", $aTemp[1])
        If DllStructGetData($Receiver2, 1) = True Then
            Return 1
        Else
            Return SetError(1, 0, 0)
        EndIf
    Else
        Return SetError(2, 0, 0)
    EndIf
EndFunc

Func _DwmEnable($WhatToDo)
    DllCall("dwmapi.dll", "uint", "DwmEnableComposition", "int", $WhatToDo)
EndFunc

My result are around 60-80ms with DWM on and around 30ms with it off. My screen is 1600x1200.

Link to comment
Share on other sites

Run on your own pc to see what times you get :(

#include <WindowsConstants.au3>
GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP)
GUISetBkColor("0xFFFFFF")
GUICtrlCreateGraphic(@DesktopWidth-2, @DesktopHeight-2, 2, 2)
GUICtrlSetBkColor(-1,"0x000000")
GUISetState()
$timer = TimerInit()
$aPixelfound = PixelSearch(1, 1, @DesktopWidth-1, @DesktopHeight-1, "0x000000")
$timer = TimerDiff($timer)
ConsoleWrite("PixelSearch took " & $timer/1000 & " Seconds To find pixel at" & @CR & "X = " & $aPixelfound[0] & @CR & "Y = " & $aPixelfound[1] & @CR)
MsgBox(0,"PixelSearch took " & $timer/1000 & " Seconds","To find pixel at" & @CR & "X = " & $aPixelfound[0] & @CR & "Y = " & $aPixelfound[1])
$hSearchInWindow = GUICreate("", 100, 100, 100, 100, $WS_POPUP)
GUISetBkColor("0x000000")
GUICtrlCreateGraphic(90, 90, 2, 2)
GUICtrlSetBkColor(-1,"0xFFFFFF")
GUISetState()
Opt("PixelCoordMode", 0)
$timer = TimerInit()
$aPixelfound = PixelSearch(0, 0, 99, 99, "0xFFFFFF", 0, 1, $hSearchInWindow)
$timer = TimerDiff($timer)
ConsoleWrite("PixelSearch in window took " & $timer/1000 & " Seconds To find pixel at" & @CR & "X = " & $aPixelfound[0] & @CR & "Y = " & $aPixelfound[1] & @CR)
MsgBox(0,"PixelSearch in window took " & $timer/1000 & " Seconds","To find pixel at" & @CR & "X = " & $aPixelfound[0] & @CR & "Y = " & $aPixelfound[1])

#cs
PixelSearch took 0.0692593611757919 Seconds To find pixel at
X = 1678
Y = 1048
PixelSearch in window took 0.000674108022108955 Seconds To find pixel at
X = 90
Y = 90
#ce
GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.
Link to comment
Share on other sites

Question. On win7 x64 (4GHz) PixelGetColor takes about 33ms/pixel. Even with DWM off it takes 10ms/pixel, so it's about 3 times faster but switching DWM off/on really tears up the screen. However, PixelSearch is blindingly fast in comparison searching a 1680x1050 screen (almost 2 million pixels) in about 150ms? What routine is PixelSearch using to get pixel color?

Edited by ahha
Link to comment
Share on other sites

It'd be my guess that PixelSearch() is grabbing the bitmap into memory using GetDIBits (see MSDN) for searching. This is what I use for reading pixels from memory (there's multiple examples of this on the web). Only issue is that you have to mask off the top 8 bits when you read it in RGB mode. The PixelGetColor() function probably directly uses GetPixel (see MSDN for this too).

Link to comment
Share on other sites

Thanks.

For others searching GetDIBits is here: http://msdn.microsoft.com/en-us/library/dd144879%28VS.85%29.aspx

and GetPixel is here: http://msdn.microsoft.com/en-us/library/dd144909%28VS.85%29.aspx

Here's a really good explanation of why GetPixel is dog SLOW.

http://social.msdn.microsoft.com/Forums/en-US/windowsuidevelopment/thread/4db649d2-4747-4773-8f9a-9b74dacc5a7d

Also found a post here subject: http://www.autoitscript.com/forum/index.php?showtopic=106407

PixelGetColor vs. _GDIPlus_BitmapLockBits posted by QED Posted 05 December 2009 - 02:43 PM

which talks about speed.

Edited by ahha
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...