Jump to content

PixelSearch w/ Occurrence Check


Knight
 Share

Recommended Posts

This function can pixelsearch a rectangle for a color and gives you the result of which occurrence you want.

_PixelSearch_Occurrence(left, top, right, bottom, color, occurrence, shade variance, step)

It isn't perfect. Its lacking error checking and the variables need to be renamed because they are too common, but it works. With the 3-5 minutes of testing it worked flawlessly, however I never stress-tested it for error-checking.

It probably isn't the fastest or most reliable way of getting this done; and the main reason I am posting it is in hope other people can improve/rebuild and we can get a real nice UDF based on this concept.

Func _PixelSearch_Occurrence($Left, $Top, $Right, $Bottom, $Color, $Occurrence = 1, $ShadeVariant = 0, $Step = 1)
    Local $X_Offset = $Left
    Local $Y_Offset = 0
    For $i = 1 To $Occurrence
        Local $Search = PixelSearch($X_Offset, $Top + $Y_Offset, $Right, $Top + $Y_Offset, $Color, $ShadeVariant, $Step)
        If @Error = 1 Then
            $Y_Offset += 1
            Local $Search = PixelSearch($Left, $Top + $Y_Offset, $Right, $Bottom, $Color, $ShadeVariant, $Step)
            If @error = 1 Then
                SetError(1)
                ExitLoop
            Else
                If $i < $Occurrence Then
                    Local $X_Offset = $Search[0] + 1
                    Local $Y_Offset = $Search[1]
                    ContinueLoop
                Else
                    ExitLoop
                EndIf
            EndIf
        Else
            If $i < $Occurrence Then
                Local $X_Offset = $Search[0] + 1
            Else
                ExitLoop
            EndIf
        EndIf
    Next
    Return $Search
EndFuncoÝ÷ ØLZ^±«­¢+ØÀÌØìÄô}A¥á±MÉ¡}=ÕÉɹ À°À°Í­Ñ½Á]¥Ñ °Í­Ñ½Á!¥¡Ð°Áá°Ì¤(ÀÌØìÈôA¥á±MÉ  À°À°Í­Ñ½Á]¥Ñ °Í­Ñ½Á!¥¡Ð°Áá¤)5Í    ½à À°ÅÕ½ÐíIÍÕ±ÑÌÅÕ½Ðì°ÅÕ½Ðí}AM
Link to comment
Share on other sites

  • Moderators

Here's my shot at it, I think I have a logic issue somewhere, but to be honest, I am too tired to find it. I added $iOptPCM = 2 ... for Opt('PixelCoordMode') for the client area of the place to search by default, then it changes it back before it returns. I don't know off hand which Beta started to allow SetError(x,[x,[x]]) but that beta is required. I also added a sleep mode default is 0 but for really big area searches, you may consider 10.

It also returns a 2 dimensional array. [0][N] = X-Coord for that N element / [1][N] Y-Coord for that N element

Example Script.

$Timer = TimerInit()
$cSearch = _PixelSearchEX(80, 54, 200, 65, 0x000000)
If IsArray($cSearch) Then
    For $i = 1 To UBound($cSearch, 2) - 1
        ConsoleWrite('X: ' & $cSearch[0][$i] & ' | Y: ' & $cSearch[1][$i] & @LF)
    Next
EndIf
ConsoleWrite(@LF & @LF & '===========' & @LF & TimerDiff($Timer) / 1000 & @LF)oÝ÷ Ù@Åjëh×6Func _PixelSearchEX($iXStart, $iYStart, $iXEnd, $iYEnd, $vColor, $iShade = 0, $iStep = 1, $iOptPCM = 2, $iSleep = 0)
    $OptPCM = Opt('PixelCoordMode', $iOptPCM)
    Local $iXCurrent = 0, $iYCurrent = 0
    Local $iXElement, $iYElement
    While 1
        $aSearch = PixelSearch(($iXStart + $iXCurrent), ($iYStart + $iYCurrent), $iXEnd, $iYEnd, $vColor, $iShade, $iStep)
        If Not IsArray($aSearch) And $iYEnd - ($iYStart + $iYCurrent) = 0 Then ExitLoop
        If IsArray($aSearch) Then
            $iXElement &= $aSearch[0] & @LF
            $iYElement &= $iYStart + $iYCurrent & @LF
            If $iXStart + $iXCurrent >= $iXEnd Then
                $iXCurrent = 0
                $iYCurrent += 1
            Else
                $iXCurrent = ($aSearch[0] - $iXStart) + 1
            EndIf
        Else
            If $iXStart + $iXCurrent >= $iXEnd Then
                $iXCurrent = 0
                $iYCurrent += 1
            Else
                $iXCurrent += 1
            EndIf
        EndIf
        Sleep($iSleep)
    WEnd
    Opt('PixelCoordMode', $OptPCM)
    If $iXElement = '' Then Return SetError(1, 0, 0)
    $iXElement = StringSplit(StringTrimRight($iXElement, 1), @LF)
    $iYElement = StringSplit(StringTrimRight($iYElement, 1), @LF)
    Local $aElements[2][UBound($iXElement)]
    For $xCount = 1 To UBound($iXElement) - 1
        $aElements[0][$xCount] = $iXElement[$xCount]
        $aElements[1][$xCount] = $iYElement[$xCount]
    Next
    Return $aElements
EndFunc
It's actually faster than I thought... but still no where as fast as it would need to be to be super effective like if PixelCheckSum() had an option for color specific. I've asked someone :D to give me a hand in that area, so that we could have more options with it, but everytime I ask, I get brushed off with no reply, so we'll have ot live with nasty work arounds like this until then.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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...