Sign in to follow this  
Followers 0
Klaatu

Looking for a more powerful PixelSearch function

8 posts in this topic

Hi. Perhaps someone has already done this, but what I'm looking for is similar to the built-in command PixelSearch, but with a better ability to specify the variation. Ideally I would be able to specify separate shade-variation values for each of R, G, or B. Or perhaps even better would be able to specify variations in hue, saturation, and brightness instead (which makes more sense to me). For example, if I were looking for any color that was green, I could use values of, say, hue=0.30 to 0.36 (greenish), saturation=0 to 1 (any saturation), and brightness=0 to 1 (any brightness). Not sure how that would translate to RGB, perhaps 255, 15, 255? Anyway hopefully I've explained myself well enough.

Any ideas how to go about accomplishing this? Perhaps an AutoIt Guru has already written something similar? I know I could use PixelGetColor in a loop though all pixels in the box specified by the coordinates, but, without having written the code to do that, I would suspect that performance would be terrible. Anyway, would appreciate any help. TIA


My Projects:DebugIt - Debug your AutoIt scripts with DebugIt!

Share this post


Link to post
Share on other sites



Hi. Perhaps someone has already done this, but what I'm looking for is similar to the built-in command PixelSearch, but with a better ability to specify the variation. Ideally I would be able to specify separate shade-variation values for each of R, G, or B. Or perhaps even better would be able to specify variations in hue, saturation, and brightness instead (which makes more sense to me). For example, if I were looking for any color that was green, I could use values of, say, hue=0.30 to 0.36 (greenish), saturation=0 to 1 (any saturation), and brightness=0 to 1 (any brightness). Not sure how that would translate to RGB, perhaps 255, 15, 255? Anyway hopefully I've explained myself well enough.

Any ideas how to go about accomplishing this? Perhaps an AutoIt Guru has already written something similar? I know I could use PixelGetColor in a loop though all pixels in the box specified by the coordinates, but, without having written the code to do that, I would suspect that performance would be terrible. Anyway, would appreciate any help. TIA

$Pixel = PixelSearch(24, 58, 1006, 735, 4864590)

While IsArray($Pixel)
  Msgbox(0,"Pixel Coordinate", $Pixel[0] & "," & $Pixel[1])
  Sleep(100)
Wend

You can start with this code for now and probably go further later on.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hi. Perhaps someone has already done this, but what I'm looking for is similar to the built-in command PixelSearch, but with a better ability to specify the variation. Ideally I would be able to specify separate shade-variation values for each of R, G, or B. Or perhaps even better would be able to specify variations in hue, saturation, and brightness instead (which makes more sense to me). For example, if I were looking for any color that was green, I could use values of, say, hue=0.30 to 0.36 (greenish), saturation=0 to 1 (any saturation), and brightness=0 to 1 (any brightness). Not sure how that would translate to RGB, perhaps 255, 15, 255? Anyway hopefully I've explained myself well enough.

Any ideas how to go about accomplishing this? Perhaps an AutoIt Guru has already written something similar? I know I could use PixelGetColor in a loop though all pixels in the box specified by the coordinates, but, without having written the code to do that, I would suspect that performance would be terrible. Anyway, would appreciate any help. TIA

$Pixel = PixelSearch(24, 58, 1006, 735, 4864590)

While IsArray($Pixel)
  Msgbox(0,"Pixel Coordinate", $Pixel[0] & "," & $Pixel[1])
  Sleep(100)
Wend

You can start with this code for now and probably go further later on.

But you have a very interesting idea here...

Edited by PixelGoodies

Share this post


Link to post
Share on other sites

$Pixel = PixelSearch(24, 58, 1006, 735, 4864590)

While IsArray($Pixel)
  Msgbox(0,"Pixel Coordinate", $Pixel[0] & "," & $Pixel[1])
  Sleep(100)
Wend

You can start with this code for now and probably go further later on.

But you have a very interesting idea here...

This is exactly what I want as well, and since I'm a programmer I guess I'll go write the DLL ... just need an example DLL which should be hard to find around here.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

This is exactly what I want as well, and since I'm a programmer I guess I'll go write the DLL ... just need an example DLL which should be hard to find around here.

OK, I made a start but didn't have time to do it in a DLL, but I did have time to write this function which might give someone else ideas. Red = 0, Green = 1, and Blue = 2 on the RGB012 parameter.

;===============================================================================
; Function Name:    RGBPixelSearch()
; Description:      similar to PixelSearch, but return when red, green, or blue
;                   is outside a limit
; Parameter(s):     x1,$y1,$x2,$y2,$RGB012,$low_limit,$high_limit,$step
; Return Value(s):  None
;                   or @error if nothing found
;author               : ironjohn
;===============================================================================
Func RGBPixelSearch($x1, $y1, $x2, $y2, $RGB012, $low_limit = -1, $high_limit = -1, $step = 1)
    For $y = $y1 To $y2 Step $step
        For $x = $x1 To $x2 Step $step
            $pixel_color = PixelGetColor($x, $y)
            $pixel_colorRGB = getRGB($pixel_color)

            If $low_limit > -1 Then
                If $high_limit > -1 Then
                    If $pixel_colorRGB[$RGB012] > $low_limit And $pixel_colorRGB[$RGB012] < $high_limit Then
                        Return
                    EndIf
                Else
                    If $pixel_colorRGB[$RGB012] > $low_limit Then
                        Return
                    EndIf
                EndIf
            Else
                If $high_limit > -1 Then
                    If $pixel_colorRGB[$RGB012] < $high_limit Then
                        Return
                    EndIf
                EndIf
            EndIf

        Next
    Next
    ;nothing found
    SetError(1)
    Return 0
EndFunc   ;==>RGBPixelSearch
Edited by ironjohn

Share this post


Link to post
Share on other sites

Oops, one more time:

Func RGBPixelSearch($x1, $y1, $x2, $y2, $RGB012, $low_limit = -1, $high_limit = -1, $step = 1)
    For $y = $y1 To $y2 Step $step
        For $x = $x1 To $x2 Step $step
            $pixel_color = PixelGetColor($x, $y)
            $pixel_colorRGB = getRGB($pixel_color,$RGB012)

            If $low_limit > -1 Then
                If $high_limit > -1 Then
                    If $pixel_colorRGB > $low_limit And $pixel_colorRGB < $high_limit Then
                        Return
                    EndIf
                Else
                    If $pixel_colorRGB > $low_limit Then
                        Return
                    EndIf
                EndIf
            Else
                If $high_limit > -1 Then
                    If $pixel_colorRGB < $high_limit Then
                        Return
                    EndIf
                EndIf
            EndIf

        Next
    Next
    ;nothing found
    SetError(1)
    Return 0
EndFunc   ;==>RGBPixelSearch

Func getRGB($color,$RGB012)
    Dim $ret
    $ret[0] = BitAND(BitShift($color, 16), 0xff)
    $ret[1] = BitAND(BitShift($color, 8), 0xff)
    $ret[2] = BitAND($color, 0xff)
    Return $ret[$RGB012]
EndFunc   ;==>getRGB

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Try this.

#include <Array.au3>

;Colour to find     = 0x7A8083 in RGB hex format(0xRRGGBB)
;Red shade variation   = ±8 of 0x7A (red channel)
;Green shade variation = ±1 of 0x80 (green channel)
;Blue shade variation  = ±4 of 0x83 (blue channel)
;Step = 5
Local $aArray = _PixelSearchRGBShades(10, 10, 500, 500, 0x7A8083, 8, 1, 4, 5)

_ArrayDisplay($aArray)

; Slightly modified from http://www.autoitscript.com/forum/topic/7485-pixelfindall/page__view__findpost__p__53108/page__view__findpost__p__53108/page__view__findpost__p__53108
Func _PixelSearchRGBShades($i_PosLeft, $i_PosTop, $i_Width, $i_Height, $i_Color, $i_RedShade = 0, $i_GrnShade = 0, $i_BluShade = 0, $i_Step = 1)
    If $i_PosLeft <> Abs(Int($i_PosLeft)) Or $i_PosTop <> Abs(Int($i_PosTop)) Or $i_Width <> Abs(Int($i_Width)) Or _
            $i_Height <> Abs(Int($i_Height)) Or $i_Color <> Abs(Int($i_Color)) Or $i_RedShade <> Abs(Int($i_RedShade)) Or _
            $i_GrnShade <> Abs(Int($i_GrnShade)) Or $i_BluShade <> Abs(Int($i_BluShade)) Or _
            $i_Step = 0 Or $i_Step <> Abs(Int($i_Step)) Or $i_Color > 0xFFFFFF Or _
            $i_PosLeft + $i_Width > @DesktopWidth Or $i_PosTop + $i_Height > @DesktopHeight Then
        Local $ai_Return[1][1]
        $ai_Return[0][0] = 0
        SetError(1)
        Return $ai_Return
    EndIf
    Local $ai_Return[$i_Width * $i_Height + 1][3]
    Local $ai_Original[3]
    Local $i_Count
    Local $i_Count_X
    Local $i_Count_Y
    Local $i_Found
    $ai_Return[0][0] = 0
    $ai_Return[0][1] = "0x" & Hex($i_Color, 6)
    $ai_Return[0][2] = "Colors Found"
    $ai_Original[0] = BitAND(BitShift($i_Color, 16), 0xff)
    $ai_Original[1] = BitAND(BitShift($i_Color, 8), 0xff)
    $ai_Original[2] = BitAND($i_Color, 0xff)
    If $i_Width / $i_Step <> Int($i_Width / $i_Step) Then
        Do
            $i_Width = $i_Width - 1
        Until $i_Width / $i_Step = Int($i_Width / $i_Step) Or $i_Width = 0
    EndIf
    If $i_Height / $i_Step <> Int($i_Height / $i_Step) Then
        Do
            $i_Height = $i_Height - 1
        Until $i_Height / $i_Step = Int($i_Height / $i_Step) Or $i_Height = 0
    EndIf
    If $i_Width = 0 And $i_Height = 0 Then
        Local $ai_Return[1][1]
        $ai_Return[0][0] = 0
        SetError(1)
        Return $ai_Return
    EndIf
    For $i_Count_X = $i_PosLeft To $i_PosLeft + $i_Width - 1 Step $i_Step
        For $i_Count_Y = $i_PosTop To $i_PosTop + $i_Height - 1 Step $i_Step
            $i_Found = PixelGetColor($i_Count_X, $i_Count_Y)
            If Abs(BitAND(BitShift($i_Found, 16), 0xff) - $ai_Original[0]) <= $i_RedShade And _
                    Abs(BitAND(BitShift($i_Found, 8), 0xff) - $ai_Original[1]) <= $i_GrnShade And _
                    Abs(BitAND($i_Found, 0xff) - $ai_Original[2]) <= $i_BluShade Then
                $i_Count = $ai_Return[0][0] + 1
                $ai_Return[0][0] = $i_Count
                $ai_Return[$i_Count][0] = $i_Count_X
                $ai_Return[$i_Count][1] = $i_Count_Y
                $ai_Return[$i_Count][2] = "0x" & Hex($i_Found, 6)
            EndIf
        Next
    Next
    $i_Count = $ai_Return[0][0]
    ReDim $ai_Return[$i_Count + 1][3]
    Return $ai_Return
EndFunc   ;==>_PixelSearchRGBShades

Edit: Link to Wolvereness post stuffed up when posted.

Edited by Malkey

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  
Followers 0