Jump to content
Sign in to follow this  

Pixel Search

Recommended Posts

Well I am going to start off my first post on this forum with a question,(Yeah thats typical I know) Please accommodate me though.

I am using pixelsearch to find colors. (Im keeping this question as general as possible) When i use pixelsearch, it finds the color i want it to, but It fixates on that same instance of the color every time it is called (I want it to find unique instances of the color each time) Is this possible?

Thanks in advance!

Edited by Hypnotix

Share this post

Link to post
Share on other sites


Welcome to these forums.

Recently, I created the function _PixelSearchNextInstance() for NoHAX who was looking for a way to get the position of the second instance of a colour using PixelSearch().

Your enquiry prompted me to create _PixelSearchNthInstance() function which continuously calls _PixelSearchNextInstance() function until the required number of instances of the colour are found.

#include <Array.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <ScreenCapture.au3>

Opt("PixelCoordMode", 0) ;1=absolute, 0=relative, 2=client

Local $i_ColourToFind = 0xFF7F27 ; In RGB hex format(0xRRGGBB)
Local $i_ShadeVariation = 0x30 ; ±30 of each colour channel of 0xFF7F27
Local $i_FindInstance = 10 ; -1     ; ( -1 for every instance)


; ===== Load specific image file ======
;Local $var = @ScriptDir & "\banner_160x400.png"
;Local $hImage = _GDIPlus_ImageLoadFromFile($var)

; or

;#cs ; ===== Select image file  ======
Local $var = FileOpenDialog("Select image", @ScriptDir & "\", "Images (*.gif;*.png;*.jpg;*.bmp)|All (*.*)", 1 + 2)
If @error Then
    MsgBox(0, "", "No File(s) chosen", 2)
Local $hImage = _GDIPlus_ImageLoadFromFile($var)

; or ===== Screen capture =====
;Local $var = _ScreenCapture_Capture("", 0, 0, 200, 200, False)
;Local $hImage = _GDIPlus_BitmapCreateFromHBITMAP($var)

Local $iX = _GDIPlus_ImageGetWidth($hImage)
Local $iY = _GDIPlus_ImageGetHeight($hImage)

Local $hWhnd = GUICreate("", $iX, $iY, 0, 0, $WS_POPUPWINDOW, $WS_EX_TOPMOST)

Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWhnd)

$aPixelPos = _PixelSearchNthInstance(0, 0, $iX, $iY, $i_ColourToFind, $i_ShadeVariation, $i_FindInstance)

If @error Then
    MsgBox(0, "Results", $aPixelPos[0][0] & " instances of 0x" & Hex($i_ColourToFind, 6) & " found.")
    MsgBox(0, "Results", $aPixelPos[0][0] & " instance of 0x" & Hex($i_ColourToFind, 6) & _
            " found at X, Y coordinadtes " & $aPixelPos[$aPixelPos[0][0]][0] & ", " & $aPixelPos[$aPixelPos[0][0]][1])


; Clean up resources

; Description: Will fill an array up to the nth instance (or the number of instances if less than nth instance) of a colour's
;                               x, y coordinates and the actual colour at those coordinates.
; Parameters:-
; $iLeft, $iTop, $iRight, $iBottom, $iColor, and $iShadeVariation are same as PixelSearch() function
; $iInstance - (Default 1) Finds the $iInstance instance of the $iColor with $iShadeVariation variation.
;                               "-1" returns all instances found
; Returns:
;           A 2D array of pixel's coordinates. (Array[1 ..n][0] = x, Array[1 ..n][1] = y, Array[1 ..n][2] = Actual pixel coour found)
;               with the number of matching pixels found in Array[0][0].
;   Success: Last row of elements in array contain the requested instance of the colour with @error = 0
; Failure: Sets @error to 1 if requested instance is not found. Array contain all instance that were found.
; Requires function  _PixelSearchNextInstance()
Func _PixelSearchNthInstance($iLeft, $iTop, $iRight, $iBottom, $iColor, $iShadeVariation = 0, $iInstance = 1)
    Local $aNextPixelPos
    Local $aCoord1stFind = PixelSearch($iLeft, $iTop, $iRight, $iBottom, $i_ColourToFind, $i_ShadeVariation); First instance of colour
    If Not @error Then
        If $iInstance = 1 Then Return SetError(0, 0, $aCoord1stFind)
        Local $aCoord1stFind[1][3] = [[0, 0, 0]]
        Return SetError(1, 0, $aCoord1stFind); If colour not found set error = 1
    If $iInstance = -1 Then $iInstance = Abs($iLeft - $iRight) * Abs($iTop - $iBottom)
    Local $aPixels[$iInstance + 1][3] = [[$iInstance, 0, "Colors Found"],[$aCoord1stFind[0], $aCoord1stFind[1], "0x" & Hex(PixelGetColor($aCoord1stFind[0], $aCoord1stFind[1]), 6)]]
    Local $aTemp = $aCoord1stFind
    For $i = 2 To $iInstance
        $aNextPixelPos = _PixelSearchNextInstance($aTemp, $iLeft, $iTop, $iRight, $iBottom, $i_ColourToFind, $i_ShadeVariation)
        If Not @error Then
            $aPixels[$i][0] = $aNextPixelPos[0]
            $aPixels[$i][1] = $aNextPixelPos[1]
            $aPixels[$i][2] = "0x" & Hex(PixelGetColor($aNextPixelPos[0], $aNextPixelPos[1]), 6)
            $aTemp = $aNextPixelPos
            $aPixels[0][0] = $i - 1
            ReDim $aPixels[$i][3]
            Return SetError(1, 0, $aPixels) ; Error = 1 required instance not found.
    Return SetError(0, 0, $aPixels)
EndFunc   ;==>_PixelSearchNthInstance

; Parameters:-
;   $aCoord1stFind - Array containing X,Y coordinates of previous pixel found.
;   $iLeft      - Left coordinate of rectangle.
;   $iTop       - Top coordinate of rectangle.
;   $iRight     - Right coordinate of rectangle.
;   $iBottom  - Bottom coordinate of rectangle.
;   $iColor     - Colour value of pixel to find (in decimal or hex).
;   $iShadeVariation [optional] - A number between 0 and 255 to indicate the allowed number of shades of
;                       variation of the red, green, and blue components of the colour. Default is 0 (exact match).
; http://www.autoitscript.com/forum/topic/123583-pixelsearch-problem/page__view__findpost__p__858571
Func _PixelSearchNextInstance($aCoord1stFind, $iLeft, $iTop, $iRight, $iBottom, $iColor, $iShadeVariation = 0)

    ; Check the rest of the line for 2nd instance of $iColor
    Local $coord = PixelSearch($aCoord1stFind[0] + 1, $aCoord1stFind[1], $iRight, $aCoord1stFind[1], $iColor, $iShadeVariation)
    If Not @error Then
        Return SetError(0, 0, $coord)
    Else ; 2nd instance Not on same line.

        ; Check all remaining lines for 2nd instance
        Local $coord = PixelSearch($iLeft, $aCoord1stFind[1] + 1, $iRight, $iBottom, $iColor, $iShadeVariation)
        If Not @error Then
            Return SetError(0, 0, $coord)
        Else ;Could not find 2nd instance of pixel.
            Return SetError(1, 0, 1); Set error to 1
EndFunc   ;==>_PixelSearchNextInstance

; Draw PNG image
Func MY_WM_PAINT($hWnd, $Msg, $wParam, $lParam)
    _WinAPI_RedrawWindow($hWhnd, 0, 0, $RDW_UPDATENOW)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
    _WinAPI_RedrawWindow($hWhnd, 0, 0, $RDW_VALIDATE)
EndFunc   ;==>MY_WM_PAINT

Share this post

Link to post
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
Sign in to follow this  

  • Create New...