Jump to content

Recommended Posts

Posted

Hi Guys,

I am using the PixelGetColor function to find a particular color on the screen.
 

For $height = 0 to @DesktopHeight 
For $width  = 0 to @DeskTopWidth 
$pixel_value = PixelGetColor($width,$height) 
$pixel_value = Hex($pixel_value,8)
If $pixel_value = "003AF2FF" Then MsgBox(0,"","Found at " & width & " x " & $height)
Next
Next

 
It's just a little test script as I am still learning.


However, I find that the script can take several minutes to complete particularly in a higher resoltion.

Q: Is there a quicker function available, or am I stuck with PixelGetColor?

Many thanks

Pete

 

Posted
1 minute ago, Panamax said:

Q: Is there a quicker function available, or am I stuck with PixelGetColor?

Personally, I would try _WinAPI_GetPixel because I find that all of the WinAPI functions from UDF are generally quite a bit faster in comparison to the built-in AutoIt functions. I use a script that tests the performance between UDF functions and built-in AutoIt functions to compare the time diff when running thousands of times to grab the average time difference.

I would suggest doing something like that as well. Compare the perf between the two functions.

Posted
17 minutes ago, Panamax said:
If $pixel_value = "003AF2FF" Then MsgBox(0,"","Found at " & width & " x " & $height)

You might also get hammered with MsgBox's slowing down your loop if you happen to have many pixels of that same value on your screen. Unless it's some situation where you know for certain that there are no other pixels of that same matching color.

Posted
5 minutes ago, paw said:

it's fast

"One of the reasons FastFind is so much quicker than AutoIt's native pixel search functions is it's use of SnapShots. A SnapShot is basically a pixel map of a specified area on screen as it looked at the time the SnapShot was taken. This pixel information is stored in active memory, which means your script can access it much, much faster than the time it would take to make a new pixel request from the screen. Once a SnapShot is taken, search operations can be performed on that SnapShot until that memory is freed or overwritten."

Yes, you could take a screenshot and search the BMP.
I forgot what thread it was at but working code ( other than this DLL ) can be found in the forum ( if you find it ).

@paw, thanks for the link. I never use pixel... anything but it looks good :)  

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted (edited)
; https://www.autoitscript.com/forum/topic/213278-is-there-a-faster-function-than-pixelgetcolor-for-finding-a-color-on-the-screen/#findComment-1546838

 ; Found at 1358 x 56 ; Processed in: 170.045 seconds vs  1.374 seconds 
 
;~ Local $hTimer = TimerInit()
;~ For $height = 0 To @DesktopHeight
;~  For $width = 0 To @DesktopWidth
;~      $pixel_value = PixelGetColor($width, $height)
;~      $pixel_value = Hex($pixel_value, 8)
;~      ; ConsoleWrite($width & ", " & $height & " = " & $pixel_value & @CRLF)
;~      If $pixel_value = "00EBD85E" Then ConsoleWrite("Found at " & $width & " x " & $height & @CRLF)
;~  Next
;~ Next
;~ ConsoleWrite("Processed in: " & Round(TimerDiff($hTimer) / 1000, 3) & " seconds " & @CRLF)
;~ Exit

#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Local $hTimer = TimerInit()
$aPixelMap = _GetPixelByColor(0, 0, @DesktopWidth, @DesktopHeight, 0xEBD85E)
ConsoleWrite("Processed in: " & Round(TimerDiff($hTimer) / 1000, 3) & " seconds " & @CRLF)

For $i = 1 To $aPixelMap[0][0]
    ConsoleWrite($i & ") Found at " & $aPixelMap[$i][0] & " x " & $aPixelMap[$i][1] & @CRLF)
Next

Func _GetPixelByColor($iLeft, $iTop, $iRight, $iBottom, $FindColor, $bFindAll = False)
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the screen area as a bitmap
    Local $hBitmap = _ScreenCapture_Capture("", $iLeft, $iTop, $iRight, $iBottom)

    ; Convert the captured bitmap to a GDI+ bitmap
    Local $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

    ; Get the width and height of the captured area
    Local $width = $iRight - $iLeft
    Local $height = $iBottom - $iTop

    ; Create an array to store found Pixel
    Local $aFoundMap[1][2] = [[0, ""]]
    Local $idx = 0
    Local $argbColor

    ; Loop through each pixel in the bitmap and retrieve its color
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            ; Get the pixel color from the bitmap in ARGB format
            $argbColor = _GDIPlus_BitmapGetPixel($hGDIPlusBitmap, $x, $y)
            ; Convert ARGB to RGB for comparison (ignore the alpha channel)
            If BitAND($argbColor, 0x00FFFFFF) = $FindColor Then
                ; ConsoleWrite($x & ", " & $y & @CRLF)
                $idx += 1
                ReDim $aFoundMap[$idx + 1][2]
                $aFoundMap[$idx][0] = $x + $iLeft
                $aFoundMap[$idx][1] = $y + $iTop
                If Not $bFindAll Then ExitLoop 2
            EndIf
        Next
    Next

    $aFoundMap[0][0] = $idx

    ; Cleanup resources
    _GDIPlus_BitmapDispose($hGDIPlusBitmap)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_Shutdown()

    Return $aFoundMap
EndFunc   ;==>_GetPixelByColor

 

Edited by ioa747

I know that I know nothing

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
  • Recently Browsing   0 members

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