PixelSearchHelper & MultiPixelSearch

Post your working scripts, libraries and tools.
User avatar
Noitalommi_2
Posts: 278
Joined: 16 Aug 2023, 10:58

PixelSearchHelper & MultiPixelSearch

Post by Noitalommi_2 » 10 May 2024, 12:48

PixelSearchHelper:

PixelSearchHelper is a tool to search small areas of the screen for the most common color. While you could search the whole screen i would not recommend it, because it would take hours, so keep the Search Rectangle small. If you want to try out larger sizes start with 200x200 and see how long it takes.
The size, the number of different colors and the search with variation increase the search time. Smaller areas up to 50x50, however, do not pose a problem and the results are available very quickly.
The result is displayed as Gui or copied to the clipboard.
PixelSearchHelper will provide the necessary coordinates and color codes to work further with PixelSearch.
Most values can be copied to the clipboard by clicking on them.
The coordinates can be relative to the screen, client or window, depending on what is set with Coordmode "Pixel".
And the Search Rectangle must be within the primary screen coordinates you can't use it at secondary screens.
If there is a color code in the clipboard, than the color can be marked in the GUI with a right click.
PSH.png
PSH.png (109.55 KiB) Viewed 250 times

Code: Select all

Class PixelSearchHelper {

    /*
    **********************************************************************************************************

    __new(X, Y, Width, Height [, BackColor])

            X, Y:

                "The X and Y coordinates of the upper left corner of the Search Rectangle."

            Width, Height:

                "Width and height of the Search Rectangle."

            BackColor:

                "Color of the Search Rectangle." default = "red"
                (https://www.autohotkey.com/docs/v2/misc/Colors.htm)

    Methods:

        Show([X, Y, Width, Height])

            "Shows the Search Rectangle"

            X, Y:

                "The X and Y coordinates of the upper left corner of the Search Rectangle." default = current coordinates

            Width, Height:

                "Width and height of the Search Rectangle." default = current size
        Hide()

            "Hides the Search Rectangle"

        SetBackColor(NewColor)

            "Sets a new color for the Search Rectangle"

            NewColor:
                (https://www.autohotkey.com/docs/v2/misc/Colors.htm)

        CheckPosScreen() ; 1/0

            "Checks whether the Search Rectangle is within the primary screen coordinates."

        CheckPosClient([&X, &Y, &Width, &Height]) ; 1/0

            "Checks whether the Search Rectangle is within the active window's client area."

            &X, &Y, &Width, &Height

                "Shows how far the search rectangle is outside the active window's client area."

        CheckPosWindow([&X, &Y, &Width, &Height]) ; 1/0

            "Checks whether the Search Rectangle is within the active window coordinates."

            &X, &Y, &Width, &Height

                "Shows how far the search rectangle is outside of the active window area."

        MoveUp()
        MoveDown()
        MoveLeft()
        MoveRight()

            "Moves or resizes the Search Rectangle in a direction"
            "The hotkey that uses this method must be a wildcard hotkey." prefix = *

        GetPixelColor()

            "Searches the screen area under the search rectangle for colors"
            "You can specify whether the coordinates are relative to the screen, client or window with CoordMode "Pixel"."

        ShowResult([MaxLines])

            "Shows the results of GetPixelColor in a gui"

            MaxLines:

                "Maximum lines allowed. More than 1079 cannot be displayed." default = 10

        CopyToClipboard()

            "Copies the results of GetPixelColor into the clipboard"

        ObjCopyToClipboard()

            "Copies the color result as a Object Literal, the coordinates and the CoordMode into the clipboard for the use with MultiPixelSearch"

    Properties:

        SizeKey:
            "Key that must be held down to change the size of the Search Rectangle." default = "Ctrl"
        ModifierKey:
            "Key that must be held down to increase movement/resizing/scrolling speed. default = "Shift""
        ColorVariation:
            "The allowed number of shades of variation in either direction of the pixel color."
            "Must be a number between 0 and 255." default = 0

    (Do not use the following properties to change the values.)

        X, Y:
            "Current X and Y coordinates of the upper left corner of the search rectangle."
        Width, Height:
            "Current width and height of the Search Rectangle."
        BackColor:
            "Current BackColor of the Search Rectangle."


    **********************************************************************************************************
    */

    __new(X, Y, Width, Height, BackColor := "red") {

        this.X := X
        this.Y := Y
        this.Width := Width
        this.Height := Height

        if !this.CheckPosScreen() {

            MsgBox("The Search Rectangle must be within the primary screen coordinates.",, 262160)
            ExitApp
        }

        this.BackColor := BackColor

        this.SizeKey := "Ctrl"
        this.ModifierKey := "Shift"

        this.ColorVariation := 0

        this.SearchRectangle := Gui("AlwaysOnTop ToolWindow -Caption -DPIScale", this.__Class "_" this.InstanceName := this.GetInstanceName())
        this.SearchRectangle.BackColor := BackColor

        this.ResultHwnd := {}
        this.Color := {Total:{}, Single:{}, Count:{}, Red:{}, Green:{}, Blue:{}}
    }

    ShowResult(MaxLines := 10) {

        if this.Color.Single.HasOwnProp(1) {

            FontSize := 13

            this.Result := Gui("AlwaysOnTop -DPIScale", this.__Class "_" this.InstanceName "_Variation " this.ColorVariation)
            this.Result.MarginY := 0
            this.Result.SetFont("Bold s" FontSize, "Courier New")
            this.Result.AddText(, A_CoordModePixel ":")
            this.Result.AddText("xm", "X1"), this.Result.SetFont("Norm")
            this.Result.AddText("yp", "(rel) = " Value := this.CoordX1rel) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("yp", "   (abs) = " Value := this.CoordX1abs) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "Y1"), this.Result.SetFont("Norm")
            this.Result.AddText("yp", "(rel) = " Value := this.CoordY1rel) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("yp", "   (abs) = " Value := this.CoordY1abs) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "X2"), this.Result.SetFont("Norm")
            this.Result.AddText("yp", "(rel) = " Value := this.CoordX2rel) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("yp", "   (abs) = " Value := this.CoordX2abs) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "Y2"), this.Result.SetFont("Norm")
            this.Result.AddText("yp", "(rel) = " Value := this.CoordY2rel) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("yp", "   (abs) = " Value := this.CoordY2abs) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("xm", "")
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "Width    "), this.Result.SetFont("Norm")
            this.Result.AddText("yp", " = " Value := this.Width) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold")
            Text := this.Result.AddText("xm", "Height   ")
            Text.GetPos(,, &Width, &Height)
            this.TextHeight := Height
            this.Result.SetFont("Norm")
            this.Result.AddText("yp", " = " Value := this.Height) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "Pixels   "), this.Result.SetFont("Norm")
            this.Result.AddText("yp", " = " Value := this.Width*this.Height) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "Colours  "), this.Result.SetFont("Norm")
            this.Result.AddText("yp", " = " Value := ObjOwnPropCount(this.Color.Single)) .OnEvent("Click", Clip.Bind(Value))
            this.Result.SetFont("Bold"), this.Result.AddText("xm", "Variation"), this.Result.SetFont("Norm")
            this.Result.AddText("yp", " = " Value := this.ColorVariation) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("xm", "")
            this.Result.AddText("xm", "")
            this.Result.AddText("yp", "")
            this.Result.SetFont("Bold")
            this.Result.AddText("yp", "0001.)")
            this.Result.SetFont("Norm")
            this.Result.AddText("yp", Value := this.Color.Single.1) .OnEvent("Click", Clip.Bind(Value))
            this.Result.AddText("yp", " ")
            this.Result.AddProgress("yp c" this.Color.Single.1 " w" Width " h" Height, 100)
            this.Result.AddText("yp", ((L:=StrLen(C := this.Color.Count.1))=1?"   " C:L=2?"  " C:L=3?" " C:C)) .OnEvent("Click", Clip.Bind(C))
            Line := this.Result.AddText("yp", " " ((L:=StrLen(V := Round(this.Color.Count.1/(this.Width*this.Height)*100, 1)))=3?"  " V:L=4?" " V:V) "% ")
            this.Result.AddText("yp", "")
            this.Result.AddText("yp", "")
            Line.GetPos(, &Y)
            this.LineY := Y

            Lines := 1
            if MaxLines > 1 {

                Loop ObjOwnPropCount(this.Color.Single)-1 {

                    Lines := I := A_Index+1

                    this.Result.AddText("xm", "")
                    this.Result.AddText("yp", "")
                    this.Result.SetFont("Bold")
                    this.Result.AddText("yp", ((L:=StrLen(I))=1?"000" I:L=2?"00" I:L=3?"0" I:I) ".)")
                    this.Result.SetFont("Norm")
                    this.Result.AddText("yp", Value := this.Color.Single.%I%) .OnEvent("Click", Clip.Bind(Value))
                    this.Result.AddText("yp", " ")
                    this.Result.AddProgress("yp c" this.Color.Single.%I% " w" Width " h" Height, 100)
                    this.Result.AddText("yp", ((L:=StrLen(C := this.Color.Count.%I%))=1?"   " C:L=2?"  " C:L=3?" " C:C)) .OnEvent("Click", Clip.Bind(C))
                    this.Result.AddText("yp", " " ((L:=StrLen(V := Round(this.Color.Count.%I%/(this.Width*this.Height)*100, 1)))=3?"  " V:L=4?" " V:V) "%")
                    this.Result.AddText("yp", "")
                    this.Result.AddText("yp", "")

                    if I = MaxLines
                        break
                }
            }

            this.Result.AddText("xm", "")
            this.Result.OnEvent("Close", Close)
            this.Result.Show()
            this.ResultHwnd.%this.Result.Hwnd% := true

            if ObjOwnPropCount(this.ResultHwnd) = 1 {

                OnMessage 0x020A, MouseWheel
                MouseWheel(wParam, *) {

                    MouseGetPos ,, &Hwnd
                    Summand := GetKeyState("Shift") ? 10 : 1
                    if (Direction := (wParam << 32 >> 48) > 0 ? 1 : -1) = 1 {

                        if Summand = 1 && this.ResultHwnd.%Hwnd% = 1
                            return
                        else if Summand = 10 && this.ResultHwnd.%Hwnd% = 1
                            return
                        else if Summand = 10 && this.ResultHwnd.%Hwnd% <= 10
                            Summand := 1
                        this.ResultHwnd.%Hwnd% := this.ResultHwnd.%Hwnd%-=Summand

                        Position := this.TextHeight*Summand*Direction
                        DllCall("ScrollWindow", "Ptr", Hwnd, "Int", 0, "Int", Position, "Ptr", 0, "Ptr", 0)
                        Sleep 10
                    }
                    else {

                        WinGetClientPos &OutX, &OutY, &OutWidth, &OutHeight, "ahk_id" Hwnd
                        Height := Round(OutHeight/this.TextHeight)
                        Head := 12+2

                        if Summand = 1 && this.ResultHwnd.%Hwnd% >= Lines-Height+Head
                            return
                        else if Summand = 10 && this.ResultHwnd.%Hwnd% >= Lines-Height+Head
                            return
                        else if Summand = 10 && this.ResultHwnd.%Hwnd% >= Lines-Height+Head-Summand
                            Summand := 1
                        this.ResultHwnd.%Hwnd% := this.ResultHwnd.%Hwnd%+=Summand

                        Position := this.TextHeight*Summand*Direction
                        DllCall("ScrollWindow", "Ptr", Hwnd, "Int", 0, "Int", Position, "Ptr", 0, "Ptr", 0)
                        Sleep 10
                    }
                }
                OnMessage 0x0204, RButton
                RButton(wParam, *) {

                    if IsXDigit(Color := A_Clipboard) && StrLen(Color) = 8 {

                        MouseGetPos ,, &Hwnd
                        Found := false
                        Loop {

                            try
                                if ControlGetText("Static" A_Index, "ahk_id" Hwnd) = Color {

                                    Found := true
                                    Count := 0
                                    Loop {

                                        try
                                            if ControlGetStyle("Static" A_Index, "ahk_id" Hwnd) & 0x4 {

                                                ControlSetStyle "-0x4", "Static" A_Index, "ahk_id" Hwnd
                                                Count++

                                                if Count = 2
                                                    break
                                            }
                                        catch TargetError
                                            break
                                    }

                                    Loop {

                                        try
                                            if ControlGetText("Static" A_Index, "ahk_id" Hwnd) = Color {

                                                ControlSetStyle "+0x4", "Static" A_Index-3, "ahk_id" Hwnd
                                                ControlSetStyle "+0x4", "Static" A_Index+5, "ahk_id" Hwnd
                                                break
                                            }
                                        catch TargetError
                                            break
                                    }

                                    ToolTip "Color: " Color "`nLine: " RTrim(ControlGetText("Static" A_Index-1, "ahk_id" Hwnd), ".)") "`nMatches: " LTrim(ControlGetText("Static" A_Index+2, "ahk_id" Hwnd), A_Space)
                                    SoundBeep 600
                                    KeyWait "RButton"
                                    ToolTip
                                }
                            catch TargetError
                                break
                        }

                        if !Found {

                            ToolTip "Color " Color " not found."
                            SoundBeep 200
                            KeyWait "RButton"
                            ToolTip
                        }
                    }
                }
            }

            Close(*) {

                this.ResultHwnd.DeleteProp(WinGetID("A"))
                if ObjOwnPropCount(this.ResultHwnd) = 0 {

                    OnMessage 0x020A, MouseWheel, 0
                    OnMessage 0x0204, RButton, 0
                }

            }

            Clip(Value, *) {

                ToolTip A_Clipboard := Value
                KeyWait "LButton"
                ToolTip
            }
        }
    }

    CloseResult() {

        Loop ObjOwnPropCount(this.ResultHwnd)
            WinClose this.__Class "_" this.InstanceName "_Variation"
        this.ResultHwnd := {}
    }

    CopyToClipboard() {

        if this.Color.Single.HasOwnProp(1) {

            A_Clipboard := ""

            Head := (
                        A_CoordModePixel ":`n"
                        "X1 (rel) = " this.CoordX1rel "   (abs) = " this.CoordX1abs "`n"
                        "Y1 (rel) = " this.CoordY1rel "   (abs) = " this.CoordY1abs "`n"
                        "X2 (rel) = " this.CoordX2rel "   (abs) = " this.CoordX2abs "`n"
                        "Y2 (rel) = " this.CoordY2rel "   (abs) = " this.CoordY2abs "`n`n"
                        "Width     = " this.Width "`n"
                        "Height    = " this.Height "`n"
                        "Pixels    = "     this.Width*this.Height "`n"
                        "Colours   = "    ObjOwnPropCount(this.Color.Single) "`n"
                        "Variation = "  this.ColorVariation "`n`n"
                    )

            Loop ObjOwnPropCount(this.Color.Single) {

                I := A_Index
                Result .=   (
                                ((L:=StrLen(I))=1?"000" I:L=2?"00" I:L=3?"0" I:I) ".) "
                                this.Color.Single.%I% " "
                                ((L:=StrLen(C := this.Color.Count.%I%))=1?"   " C:L=2?"  " C:L=3?" " C:C) " "
                                ((L:=StrLen(V := Round(this.Color.Count.%I%/(this.Width*this.Height)*100, 1)))=3?"  " V:L=4?" " V:V) "% ("
                                ((L:=StrLen(C := this.Color.Red.%I%))=1?"  " C:L=2?" " C:C) ", "
                                ((L:=StrLen(C := this.Color.Green.%I%))=1?"  " C:L=2?" " C:C) ", "
                                ((L:=StrLen(C := this.Color.Blue.%I%))=1?"  " C:L=2?" " C:C) ") `n"
                            )
            }
            A_Clipboard := Head . Result
            ClipWait
        }
    }

    ObjCopyToClipboard() {

        if this.Color.Single.HasOwnProp(1) {

            A_Clipboard := ""
            Loop ObjOwnPropCount(this.Color.Single)
                Result .= this.Color.Single.%A_Index% ":" this.Color.Count.%A_Index% (!Mod(A_Index, 10) ? (",`n" A_Tab A_Tab A_Tab) : ", ")
            A_Clipboard := (
                                "CoordMode `"Pixel`", `"" A_CoordModePixel "`"`n`n"
                                "X1 := " this.CoordX1abs "`n"
                                "Y1 := " this.CoordY1abs "`n"
                                "X2 := " this.CoordX2abs "`n"
                                "Y2 := " this.CoordY2abs "`n`n"
                                "Colors := { " RTrim(Result, ", ") " }"
                            )
            ClipWait
        }
    }

    GetPixelColor() {

        this.Hide()

        Switch A_CoordModePixel {
            Case "Screen":
                this.CoordX1abs := this.X
                this.CoordY1abs := this.Y
                this.CoordX1rel := Round(this.X/A_ScreenWidth, 5)
                this.CoordY1rel := Round(this.Y/A_ScreenHeight, 5)

                this.CoordX2abs := this.X+this.Width
                this.CoordY2abs := this.Y+this.Height
                this.CoordX2rel := Round((this.X+this.Width)/A_ScreenWidth, 5)
                this.CoordY2rel := Round((this.Y+this.Height)/A_ScreenHeight, 5)
            Case "Client":
                if !this.CheckPosClient(&X, &Y, &Width, &Height) {

                    if X+Y < 0
                        MsgBox("X or Y coordinate of the Search Rectangle are outside of the active window's client area.`n`n"
                        (X < 0 ? ("X= " X) : "") "`n" (Y < 0 ? ("Y= " Y) : ""),, 262160)
                    if Width+Height < 0
                        MsgBox("Width or Height of the Search Rectangle are outside of the active window's client area.`n`n"
                        (Width < 0 ? ("Width= " Width) : "") "`n" (Height < 0 ? ("Height= " Height) : ""),, 262160)
                    this.Show()
                    return
                }
                WinGetClientPos &ClientX, &ClientY, &ClientWidth, &ClientHeight, "A"

                this.CoordX1abs := this.X-ClientX
                this.CoordY1abs := this.Y-ClientY
                this.CoordX1rel := Round((this.X-ClientX)/ClientWidth, 5)
                this.CoordY1rel := Round((this.Y-ClientY)/ClientHeight, 5)

                this.CoordX2abs := this.X-ClientX+this.Width
                this.CoordY2abs := this.Y-ClientY+this.Height
                this.CoordX2rel := Round((this.X-ClientX+this.Width)/ClientWidth, 5)
                this.CoordY2rel := Round((this.Y-ClientY+this.Height)/ClientHeight, 5)
            Case "Window":
                if !this.CheckPosWindow(&X, &Y, &Width, &Height) {

                    if X+Y < 0
                        MsgBox("X or Y coordinate of the Search Rectangle are outside of the active window's area.`n`n"
                        (X < 0 ? ("X= " X) : "") "`n" (Y < 0 ? ("Y= " Y) : ""),, 262160)
                    if Width+Height < 0
                        MsgBox("Width or Height of the Search Rectangle are outside of the active window's area.`n`n"
                        (Width < 0 ? ("Width= " Width) : "") "`n" (Height < 0 ? ("Height= " Height) : ""),, 262160)
                    this.Show()
                    return
                }
                WinGetPos &WinX, &WinY, &WinWidth, &WinHeight, "A"

                this.CoordX1abs := this.X-WinX
                this.CoordY1abs := this.Y-WinY
                this.CoordX1rel := Round((this.X-WinX)/WinWidth, 5)
                this.CoordY1rel := Round((this.Y-WinY)/WinHeight, 5)

                this.CoordX2abs := this.X-WinX+this.Width
                this.CoordY2abs := this.Y-WinY+this.Height
                this.CoordX2rel := Round((this.X-WinX+this.Width)/WinWidth, 5)
                this.CoordY2rel := Round((this.Y-WinY+this.Height)/WinHeight, 5)
        }

        ColorCount  := []
        VariationCount := []
        GetPixel := {Total:{}, Single:{}, Count:{}, VariationCount:{}, Red:{}, Green:{}, Blue:{}}
        this.Color := {Total:{}, Single:{}, Count:{}, Red:{}, Green:{}, Blue:{}}

        HDC := DllCall("GetDC", "Ptr", 0, "Ptr")
        HCDC := DllCall("CreateCompatibleDC", "Ptr", HDC, "Ptr")
        HBITMAP := DllCall("CreateCompatibleBitmap", "Ptr", HDC, "Int", this.Width, "Int", this.Height, "Ptr")
        DllCall("SelectObject", "Ptr", HCDC, "Ptr", HBITMAP)
        DllCall("BitBlt",   "Ptr", HCDC,
                            "Int", 0,
                            "Int", 0,
                            "Int", this.Width,
                            "Int", this.Height,
                            "Ptr", HDC,
                            "Int", this.X,
                            "Int", this.Y,
                            "UInt", 0xCC0020)

        TotalCount := SingleCount := 0
        Loop this.Height {

            Index := A_Index
            Loop this.Width {

                BGR := DllCall("GetPixel", "Ptr", HCDC, "Int", A_Index-1, "Int", Index-1, "UInt")
                Red := BGR & 0xFF
                Green := (BGR & 0xFF00) >> 8
                Blue := (BGR & 0xFF0000) >> 16
                RGB := Format("0x{:06X}", Blue & 0xFF | Green << 8 | Red << 16)

                ColorExist := false
                For , Color in GetPixel.Single.OwnProps()
                    if Color = RGB {

                        ColorExist := true
                        break
                    }
                if !ColorExist {

                    GetPixel.Single.%++SingleCount% := RGB
                    GetPixel.Red.%SingleCount% := Red
                    GetPixel.Green.%SingleCount% := Green
                    GetPixel.Blue.%SingleCount% := Blue
                }

                GetPixel.Total.%++TotalCount% := this.Color.Total.%TotalCount% := RGB
            }
        }

        DllCall("ReleaseDC", "Ptr", 0, "Ptr", HDC)
        DllCall("DeleteDC", "Ptr", HCDC)
        DllCall("DeleteObject", "Ptr", HBITMAP)

        For propCount, sColor in GetPixel.Single.OwnProps() {

            Count := 0
            Props := []
            For Index, tColor in GetPixel.Total.OwnProps() {
                if sColor = tColor {

                    Count++
                    Props.Push(Index)
                }
            }
            ColorCount.Push(Count)
            GetPixel.Count.%propCount% := Count

            For , Index in Props
                GetPixel.Total.DeleteProp(Index)
        }

        if IsInteger(this.ColorVariation) {

            if this.ColorVariation < 0
                this.ColorVariation := 0
            else if this.ColorVariation > 255
                this.ColorVariation := 255
        } else this.ColorVariation := 0

        if V := this.ColorVariation {

            For Index in GetPixel.Single.OwnProps() {

                R := GetPixel.Red.%Index%
                G := GetPixel.Green.%Index%
                B := GetPixel.Blue.%Index%

                C := 0
                For I in GetPixel.Single.OwnProps() {

                    vR := GetPixel.Red.%I%
                    vG := GetPixel.Green.%I%
                    vB := GetPixel.Blue.%I%

                    if R-V <= vR && vR-V <= R
                    && G-V <= vG && vG-V <= G
                    && B-V <= vB && vB-V <= B
                    && !(vR = R && vG = G && vB = B)
                        C += GetPixel.Count.%I%
                }
                VariationCount.Push(Value := GetPixel.Count.%Index%+C)
                GetPixel.VariationCount.%Index% := Value
            }

            Loop ObjOwnPropCount(GetPixel.Single) {

                propCount := A_Index
                MaxCount := Max(VariationCount*)
                For Index, Count in GetPixel.VariationCount.OwnProps()
                    if MaxCount = Count {

                        this.Color.Single.%propCount% := GetPixel.Single.%Index%
                        this.Color.Red.%propCount% := GetPixel.Red.%Index%
                        this.Color.Green.%propCount% := GetPixel.Green.%Index%
                        this.Color.Blue.%propCount%  := GetPixel.Blue.%Index%
                        this.Color.Count.%propCount% := GetPixel.VariationCount.%Index%

                        GetPixel.Single.DeleteProp(Index)
                        GetPixel.Red.DeleteProp(Index)
                        GetPixel.Green.DeleteProp(Index)
                        GetPixel.Blue.DeleteProp(Index)
                        GetPixel.VariationCount.DeleteProp(Index)
                        break
                    }
                    For Index, Count in VariationCount
                        if MaxCount = Count {

                            I := Index
                            break
                        }
                VariationCount.RemoveAt(I)
            }
        }
        else {

            Loop ObjOwnPropCount(GetPixel.Single) {

                propCount := A_Index
                MaxCount := Max(ColorCount*)
                For Index, Count in GetPixel.Count.OwnProps()
                    if MaxCount = Count {

                        this.Color.Single.%propCount% := GetPixel.Single.%Index%
                        this.Color.Red.%propCount% := GetPixel.Red.%Index%
                        this.Color.Green.%propCount% := GetPixel.Green.%Index%
                        this.Color.Blue.%propCount%  := GetPixel.Blue.%Index%
                        this.Color.Count.%propCount% := GetPixel.Count.%Index%

                        GetPixel.Single.DeleteProp(Index)
                        GetPixel.Red.DeleteProp(Index)
                        GetPixel.Green.DeleteProp(Index)
                        GetPixel.Blue.DeleteProp(Index)
                        GetPixel.Count.DeleteProp(Index)
                        break
                    }
                    For Index, Count in ColorCount
                    if MaxCount = Count {

                        I := Index
                        break
                    }
                ColorCount.RemoveAt(I)
            }
        }

        GetPixel := ""
        this.Show()
    }

    MoveUp() => this.ChangePos("Up")
    MoveDown() => this.ChangePos("Down")
    MoveLeft() => this.ChangePos("Left")
    MoveRight() => this.ChangePos("Right")
    ChangePos(Direction) {

        SW := A_ScreenWidth
        SH := A_ScreenHeight

        M := GetKeyState(this.ModifierKey) ? 10 : 1
        if GetKeyState(this.SizeKey) {

            Switch Direction {
                Case "Up": this.Height := (H := this.Height-M) < 1 ? 1 : H
                Case "Down": this.Height := (H := this.Height+M)+this.Y > SH ? SH-this.Y : H
                Case "Left": this.Width := (W := this.Width-M) < 1 ? 1 : W
                Case "Right": this.Width := (W := this.Width+M)+this.X > SW ? SW-this.X : W
            }
            this.SearchRectangle.Move(,,this.Width, this.Height)
        }
        else {

            Switch Direction {
                Case "Up": this.Y := (Y := this.Y-M) < 0 ? 0 : Y
                Case "Down": this.Y := (Y := this.Y+M)+this.Height > SH ? SH-this.Height : Y
                Case "Left": this.X := (X := this.X-M) < 0 ? 0 : X
                Case "Right": this.X := (X := this.X+M)+this.Width > SW ? SW-this.Width : X
            }
            this.SearchRectangle.Move(this.X, this.Y)
        }
    }

    Move(X := this.X, Y := this.Y, Width := this.Width, Height := this.Height) {

        this.SearchRectangle.Move(this.X := X,
                                  this.Y := Y,
                                  this.Width := Width,
                                  this.Height := Height)
    }

    Show(X := this.X, Y := this.Y, Width := this.Width, Height := this.Height) {

        this.SearchRectangle.Show("x" (this.X := X)
                                 " y" (this.Y := Y)
                                 " w" (this.Width := Width)
                                 " h" (this.Height := Height)
                                 " NoActivate")
    }

    Hide() {

        this.SearchRectangle.Hide()
    }

    SetBackColor(NewColor) {

        this.SearchRectangle.BackColor := NewColor
    }

    CheckPosClient(&X?, &Y?, &Width?, &Height?) {

        WinGetClientPos &ClientX, &ClientY, &ClientWidth, &ClientHeight, "A"

        X := (r := this.X-ClientX) < 0 ? r : 0
        Y := (r := this.Y-ClientY) < 0 ? r : 0
        Width := (r := ClientX+ClientWidth-this.X-this.Width) < 0 ? r : 0
        Height := (r := ClientY+ClientHeight-this.Y-this.Height) < 0 ? r : 0

        return this.X >= ClientX && this.Y >= ClientY && this.X+this.Width <= ClientX+ClientWidth && this.Y+this.Height <= ClientY+ClientHeight ? 1 : 0
    }

    CheckPosWindow(&X?, &Y?, &Width?, &Height?) {

        WinGetPos &WinX, &WinY, &WinWidth, &WinHeight, "A"

        X := (r := this.X-WinX) < 0 ? r : 0
        Y := (r := this.Y-WinY) < 0 ? r : 0
        Width := (r := WinX+WinWidth-this.X-this.Width) < 0 ? r : 0
        Height := (r := WinY+WinHeight-this.Y-this.Height) < 0 ? r : 0

        return this.X >= WinX && this.Y >= WinY && this.X+this.Width <= WinX+WinWidth && this.Y+this.Height <= WinY+WinHeight ? 1 : 0
    }

    CheckPosScreen() => this.X >= 0 && this.X + this.Width <= A_ScreenWidth && this.Y >=0 && this.Y + this.Height <= A_ScreenHeight ? 1 : 0
    GetInstanceName() => SubStr((Err := Error(,-2), S := Err.Stack), P := InStr(S, "]",,, 2)+2 , InStr(S, ":=",,,3)-P)
}
Example:

Code: Select all

#Requires AutoHotkey 2.0
#SingleInstance
#Include "PixelSearchHelper.ahk"

CoordMode "Pixel", "Screen"

Rect := PixelSearchHelper(0, 0, 25, 25, 0xFF0000) ; creates a red 25x25 Search Rectangle at the top left screen corner

Rect.Show() ; shows the Search Rectangle

F1:: {

    Rect.GetPixelColor() ; searches for colors
    Rect.CopyToClipboard() ; copys the result to the Clipboard
    Rect.ShowResult(100) ; shows a Gui with the results, max 100
}


F2:: {

    ; runs the search 5 times and increases the color variation by 1 each time up to ColorVariation 4
    Loop 5 {

        Rect.ColorVariation := A_Index-1
        Rect.GetPixelColor()
        Rect.ShowResult(100)
    }
}

; the hotkeys to move the Search Rectangle
; use Ctrl to resize the Rectangle and Shift to move or resize it faster
*Up::Rect.MoveUp()
*Down::Rect.MoveDown()
*Left::Rect.MoveLeft()
*Right::Rect.MoveRight()
MultiPixelSearch:

MultiPixelSearch searches a small screen area for the specified colors.
Info: If you try this on the desktop then remember that all windows have a shadow area. To completely exclude this shadow area, you need to search with a variation of at least 14.

Code: Select all

MultiPixelSearch(X1, Y1, X2, Y2, Colors, Variation := 0) { ; 0/1

    /*324
        X1, Y1 =    The X and Y coordinates of the top left corner of the rectangle to search.
        X2, Y2 =    The X and Y coordinates of the bottom right corner of the rectangle to search.

                    (Coordinates are relative to the area specified with CoordMode "Pixel")

        Colors =    {Color: Number [, Color2: Number2, ...]}
                    Object literal, the property name is the color (24bit hex rgb) to search for and the value is the number of expected matches.

        Variation = A number between 0 and 255 to indicate the allowed number of shades of variation in either direction for the intensity of the red, green, and blue components of the color.
                    If omitted, it defaults to 0
    */

    Switch A_CoordModePixel {
        Case "Screen":
            X := X1
            Y := Y1
        Case "Client":
            WinGetClientPos &ClientX, &ClientY, &ClientWidth, &ClientHeight, "A"
            X := ClientX+X1
            Y := ClientY+Y1
        Case "Window":
            WinGetPos &WinX, &WinY, &WinWidth, &WinHeight, "A"
            X := WinX+X1
            Y := WinY+Y1
    }

    Width := X2-X1
    Height := Y2-Y1

    Colors_ := {}
    for Color, Number in Colors.OwnProps()
        Colors_.%Color% := Number

    HDC := DllCall("GetDC", "Ptr", 0, "Ptr")
    HCDC := DllCall("CreateCompatibleDC", "Ptr", HDC, "Ptr")
    HBITMAP := DllCall("CreateCompatibleBitmap", "Ptr", HDC, "Int", Width, "Int", Height, "Ptr")
    DllCall("SelectObject", "Ptr", HCDC, "Ptr", HBITMAP)
    DllCall("BitBlt", "Ptr", HCDC, "Int", 0, "Int", 0, "Int", Width, "Int", Height, "Ptr", HDC, "Int", X, "Int", Y, "UInt", 0xCC0020)

    Loop Height {

        Index := A_Index
		Loop Width {

			if Check()
				return 1
			BGR := DllCall("GetPixel", "Ptr", HCDC, "Int", A_Index-1, "Int", Index-1, "UInt")
            if V := Variation {

                R :=  BGR & 0xFF
                G := (BGR & 0xFF00) >> 8
                B := (BGR & 0xFF0000) >> 16
                for Color, Count in Colors_.OwnProps() {

                    vR := (Color & 0xFF0000) >> 16
                    vG := (Color & 0xFF00) >> 8
                    vB :=  Color & 0xFF
                    if R-V <= vR && vR-V <= R
                    && G-V <= vG && vG-V <= G
                    && B-V <= vB && vB-V <= B
                        Colors_.%Color% := Count-1
                }
            }
            else {

                RGB := BGR >> 16 & 0xFF | BGR & 0xFF00 | (BGR & 0xFF) << 16
                for Color, Count in Colors_.OwnProps()
                    if Color = RGB {

                        Colors_.%Color% := Count-1
                        break
                    }
            }
        }
    }

    if Check()
        return 1
    Finish()
    return 0

    Check() {

        for , Count in Colors_.OwnProps()
            if Count > 0
                return
        Finish()
        return 1
    }

    Finish() {

		DllCall("ReleaseDC", "Ptr", 0, "Ptr", HDC)
        DllCall("DeleteDC", "Ptr", HCDC)
        DllCall("DeleteObject", "Ptr", HBITMAP)
    }
}
Example 1:

Code: Select all

#Requires AutoHotkey 2.0
#SingleInstance
#Include "MultiPixelSearch.ahk"


; Searches the specified screen area for 10 white pixels
F1:: {

    CoordMode "Pixel", "Screen"

    X1 := 3161
    Y1 := 1013
    X2 := 3171
    Y2 := 1023

    Colors := { 0xFFFFFF:10 }

    if MultiPixelSearch(X1, Y1, X2, Y2, Colors)
        MsgBox "found"
    else
        MsgBox "not found"
}

; Searches the specified client area for a white, black, red, green and blue pixel with a variation of 10
F2:: {

    CoordMode "Pixel", "Client"

    X1 := 3161
    Y1 := 1013
    X2 := 3171
    Y2 := 1023

    Colors := { 0xFFFFFF:1, 0x000000:1, 0xFF0000:1, 0x00FF00:1, 0x0000FF:1 }

    if MultiPixelSearch(X1, Y1, X2, Y2, Colors, 10)
        MsgBox "found"
    else
        MsgBox "not found"
}
Example 2:

You can use the ObjCopyToClipboard() method of PixelSearchHelper to get the needed color codes quickly.

Code: Select all

#Requires AutoHotkey 2.0
#SingleInstance
#Include "MultiPixelSearch.ahk"


; Searches for a lot of different colors in the specified area
; The Object literal was created using the ObjCopyToClipboard() method of PixelSearchHelper
F1:: {

    CoordMode "Pixel", "Screen"

    X1 := 420
    Y1 := 773
    X2 := 465
    Y2 := 818

    Colors := { 0x000000:75, 0x2A2A2A:42, 0x555555:41, 0x616161:33, 0x161616:31, 0xFDFDFD:16, 0x2C2C2C:14, 0x3E5D4E:12, 0x374F3F:10, 0x2B2B2B:8,
                0x2AC2D1:8, 0x203226:7, 0x2C2D2C:7, 0x39523D:7, 0x213327:6, 0x0179D4:6, 0x3F604F:6, 0x3C5444:6, 0x374F40:6, 0x0D559D:5,
                0x263C30:5, 0x263D31:5, 0x0E5299:5, 0x426551:5, 0x949A90:4, 0x284330:4, 0x027AD5:4, 0x027BD5:4, 0x0E549C:4, 0x0078D4:4,
                0x0E539A:4, 0x017AD5:4, 0x0F5197:4, 0x0F5096:4, 0x0F5094:4, 0x426252:4, 0x333333:4, 0x3D5547:4, 0x476857:4, 0x364D40:4,
                0x2A3E33:4, 0x0C88DA:3, 0x0D8ADB:3, 0x0883D8:3, 0x213227:3, 0x2A432E:3, 0x047ED6:3, 0x313131:3, 0x0F4F93:3, 0x303030:3,
                0x426350:3, 0x43634E:3, 0x436453:3, 0x476757:3, 0x41624F:3, 0x456455:3, 0x353430:3, 0x3F5C4F:3, 0x415A4D:3, 0x3C5445:3,
                0x3D5546:3, 0x3A5343:3, 0x272727:3, 0x39523F:3, 0x364E3E:3, 0x374F3E:3, 0x39513D:3, 0x38503D:3, 0x2B4135:3, 0xF7F7F7:3,
                0xFBFAF6:3, 0x446655:3, 0x0F8CDC:2, 0x2F453A:2, 0x0985D9:2, 0x2E433A:2, 0x0A86D9:2, 0x2D4238:2, 0x223326:2, 0xA4A79E:2,
                0x057ED6:2, 0x0680D7:2, 0x0781D7:2, 0x0984D9:2, 0x2C4334:2, 0x223428:2, 0x223227:2, 0x101413:2, 0x047DD6:2, 0x26392E:2,
                0x24362A:2, 0xA7AAA1:2, 0x037CD5:2, 0x057FD7:2, 0x037DD6:2, 0x0C5499:2, 0x24362B:2, 0x3B5047:2, 0x27402E:2, 0x283F31:2,
                0xA2A79D:2, 0x0B5094:2, 0x0D5499:2, 0x0D559E:2, 0x1D1D1D:2, 0xCBCBCB:2, 0x436654:2, 0x273C30:2, 0x273B2F:2, 0x466856:2,
                0x4B6C59:2, 0x94B0CE:2, 0x253C2F:2, 0x253C30:2, 0x253B2F:2, 0x0D549C:2, 0x4E6F5E:2, 0x466659:2, 0x476956:2, 0x4A6B5A:2,
                0x4C6C5D:2, 0x446356:2, 0x416250:2, 0x42634E:2, 0x456756:2, 0x4B6A5B:2, 0x2A2A26:2, 0x485E52:2, 0x40614F:2, 0x436452:2,
                0x292923:2, 0x415E52:2, 0x394B43:2, 0x456555:2, 0x2D2D2D:2, 0x3E5E4E:2, 0x405E4F:2, 0xEFEFEF:2, 0x405C4E:2, 0x3F5D4F:2,
                0x405F50:2, 0x406050:2, 0x3E5C4F:2, 0x3F5F50:2, 0x4F7069:2, 0x3F5D55:2, 0x292921:2, 0x3F5A4D:2, 0x3E5648:2, 0x434343:2,
                0x363636:2, 0x3E5548:2, 0x3A3A36:2, 0x476958:2, 0x565656:2, 0x3B5442:2, 0x3C5443:2, 0x4D6E5D:2, 0xE6E6E6:2, 0x395240:2,
                0x3A5340:2, 0x4F705F:2, 0x3A5342:2, 0x38523F:2, 0x517260:2, 0x36503F:2, 0x38523D:2, 0x32413A:2, 0x39503E:2, 0x767676:2,
                0x384E40:2, 0x354D3E:2, 0x38503E:2, 0x364E40:2, 0x33493D:2, 0x33483C:2, 0x30C1E1:2, 0x2FC4D8:2, 0x32483B:2, 0x31473A:2,
                0x51C7F5:2, 0x2EC2DB:2, 0x334A3D:2, 0x2F4638:2, 0x2F4537:2, 0xFCFBF9:2, 0x34C0F4:2, 0x31C1E8:2, 0x2BC2D5:2, 0x514E48:2,
                0x3FD1B4:2, 0x324A3D:2, 0x2C4135:2, 0x33473C:2, 0x2B3F34:2, 0x373737:2, 0x4A695C:2, 0x33443A:2, 0x2D4338:2, 0x486A57:2,
                0x3D5347:1, 0x4A6C5B:1, 0xF9E0C3:1, 0xF7E1C7:1, 0xFAEBD0:1, 0xFDF3D7:1, 0xF5F1D7:1, 0x848C7A:1, 0x38463B:1, 0x2B3B31:1,
                0x293C31:1, 0xD2D5D0:1, 0x4E6F5D:1, 0xFCFCFB:1, 0xFBFAFA:1, 0xF5F4F4:1, 0xFDFBFC:1, 0xFDFCF8:1, 0x39B8F0:1, 0x1C98DC:1,
                0x0A7FCC:1, 0x0C85D4:1, 0x0D88D8:1, 0x4E705E:1, 0x0F8BDA:1, 0x108DDB:1, 0x128FDC:1, 0x1391DC:1, 0x1592DC:1, 0x1592D9:1,
                0x168FD1:1, 0x1786C3:1, 0x20A0C3:1, 0x2FC4C3:1, 0x4E705D:1, 0x31C6C1:1, 0x3ACBAE:1, 0x3CCBA2:1, 0x2F4639:1, 0x304739:1,
                0x2F4637:1, 0x2F4538:1, 0x2C4235:1, 0x2F3B2F:1, 0x615346:1, 0x4F715E:1, 0xA98D7C:1, 0xC7AF9B:1, 0xB49B87:1, 0xA28674:1,
                0xC3A794:1, 0xECD9BF:1, 0xFBEFD3:1, 0xF6EFD2:1, 0x9B9F8F:1, 0x313F35:1, 0x50715F:1, 0x26362D:1, 0x4E5C53:1, 0xBFC0BB:1,
                0xDFDEDB:1, 0xDFDFDC:1, 0xD8D7D5:1, 0xD4D2D2:1, 0xE2E1E0:1, 0xF1F0EB:1, 0x29A9EB:1, 0x507261:1, 0x087CCD:1, 0x0982D5:1,
                0x0B87D9:1, 0x108EDC:1, 0x1290DD:1, 0x1392DE:1, 0x1A87CB:1, 0x517361:1, 0x135B82:1, 0x1A5976:1, 0x157FB8:1, 0x29BAC8:1,
                0x32C4B3:1, 0x3AC89F:1, 0x3ECC9F:1, 0x2F4539:1, 0x2E4439:1, 0x527363:1, 0x2E4438:1, 0x2A3930:1, 0x283228:1, 0x35362B:1,
                0x403C2F:1, 0x3C392B:1, 0x393528:1, 0x4F493B:1, 0xA59481:1, 0xDAC5AD:1, 0x547464:1, 0xF0E1C7:1, 0x85806F:1, 0x2C3029:1,
                0x273129:1, 0x3B473E:1, 0x9A9C97:1, 0xABAEA6:1, 0xB1B4AC:1, 0xAEB1A8:1, 0xA6A9A0:1, 0x3D5448:1, 0x537463:1, 0x9EA097:1,
                0x9DA097:1, 0x1794DF:1, 0x077ED4:1, 0x0882D7:1, 0x0B86D9:1, 0x108BD8:1, 0x1360A4:1, 0x0E1917:1, 0x567566:1, 0x0E1A18:1,
                0x212F2B:1, 0x28342F:1, 0x2AAABA:1, 0x33C4B0:1, 0x3BC99D:1, 0x43CD8E:1, 0x2E423A:1, 0x2C433A:1, 0x587668:1, 0x2D4137:1,
                0x2A3C33:1, 0x28362D:1, 0x253026:1, 0x242F21:1, 0x232E20:1, 0x212E23:1, 0x232E25:1, 0x3E3E33:1, 0x897B67:1, 0x5A7668:1,
                0xB09D87:1, 0x443D33:1, 0x212322:1, 0x232924:1, 0x2B332C:1, 0x8D928B:1, 0x9FA49B:1, 0xA5A9A0:1, 0xA7ABA1:1, 0x999E94:1,
                0x53655A:1, 0x90958B:1, 0x868C82:1, 0x118CDD:1, 0x067FD5:1, 0x0781D8:1, 0x0C589B:1, 0x0E3150:1, 0x0D1815:1, 0x555751:1,
                0x0F1B18:1, 0x25342C:1, 0x27342D:1, 0x3198A7:1, 0x36C5A0:1, 0x39C69A:1, 0x3EC786:1, 0x2D4239:1, 0x2C4336:1, 0x4E4E48:1,
                0x2D4335:1, 0x26372C:1, 0x233328:1, 0x223327:1, 0x233227:1, 0x222F24:1, 0x2F3428:1, 0x4F4B3D:1, 0x1D1F1B:1, 0x57564F:1,
                0x181B1A:1, 0x1B201E:1, 0x1D2520:1, 0x636863:1, 0xA2A59E:1, 0xA6A99F:1, 0x989C93:1, 0x94988E:1, 0x878E84:1, 0x56534C:1,
                0x047CD4:1, 0x0B6DB7:1, 0x0B4D8D:1, 0x0E3250:1, 0x0E1814:1, 0x17231F:1, 0x534D46:1, 0x28382E:1, 0x27342C:1, 0x2E7A69:1,
                0x36C193:1, 0x3CC382:1, 0x40C67C:1, 0x2C4237:1, 0x2C4333:1, 0x2B4234:1, 0x3E5448:1, 0x534A41:1, 0x2B4134:1, 0x2A4033:1,
                0x273A2D:1, 0x243629:1, 0x213126:1, 0x222F25:1, 0x59524B:1, 0x1F2A20:1, 0x111814:1, 0x131716:1, 0x151A18:1, 0x414441:1,
                0xA9ACA4:1, 0xA8ABA1:1, 0xA6AAA1:1, 0x999F95:1, 0x534E48:1, 0x91978D:1, 0x037CD4:1, 0x0A5092:1, 0x0C4F91:1, 0x0D3C67:1,
                0x101916:1, 0x333E3A:1, 0x28372D:1, 0x302E2B:1, 0x26322B:1, 0x2FAF8E:1, 0x36BF8A:1, 0x3BC17C:1, 0x41C56F:1, 0x2B4332:1,
                0x2A432F:1, 0x2B442F:1, 0x2C4131:1, 0x334037:1, 0x2A3E32:1, 0x1F2E23:1, 0x1E2720:1, 0x151B17:1, 0x111512:1, 0x282D29:1,
                0xA6A8A2:1, 0x4E6A5D:1, 0xA7ACA2:1, 0x9EA59A:1, 0x989E94:1, 0x9CA298:1, 0x0478D4:1, 0x0681D7:1, 0x4D6D60:1, 0x0974C5:1,
                0x0B4E90:1, 0x0C5296:1, 0x0B5292:1, 0x111A17:1, 0x495953:1, 0x25382D:1, 0x285442:1, 0x35BE87:1, 0x37BF84:1, 0x4C6C5E:1,
                0x3DC172:1, 0x3EC26F:1, 0x294431:1, 0x28422F:1, 0x29422F:1, 0x284031:1, 0x273D2F:1, 0x263B2E:1, 0x26392D:1, 0x48695A:1,
                0x213026:1, 0x212C24:1, 0x1E2922:1, 0x171F1B:1, 0x101612:1, 0x181D19:1, 0xA4A8A2:1, 0xA9ACA3:1, 0xA5AAA1:1, 0xA0A69C:1,
                0x48685B:1, 0x969C92:1, 0x979D94:1, 0x157CCB:1, 0x086AB7:1, 0x0B4F92:1, 0x144779:1, 0x3E5549:1, 0x46675A:1, 0x4B5954:1,
                0x25332A:1, 0x307859:1, 0x35B574:1, 0x3BBF71:1, 0x3EC068:1, 0x294230:1, 0x28402F:1, 0x26402D:1, 0x27402C:1, 0x27402D:1,
                0x273D31:1, 0x263B2F:1, 0x213127:1, 0x1E2E24:1, 0x1C2921:1, 0x18241C:1, 0x19201A:1, 0x9FA59D:1, 0xABAEA5:1, 0x9EA49A:1,
                0x989E95:1, 0x939991:1, 0x4587B4:1, 0x0179D5:1, 0x0769B8:1, 0x21517B:1, 0x213429:1, 0x243229:1, 0x294133:1, 0x293F32:1,
                0x273F2E:1, 0x273F2D:1, 0x273F2F:1, 0x284032:1, 0x273F32:1, 0x283F32:1, 0x25392D:1, 0x253729:1, 0x213325:1, 0x1F2F25:1,
                0x1D2D22:1, 0x1B2A1F:1, 0x222B22:1, 0x969C94:1, 0x9EA399:1, 0x9CA398:1, 0x4A6B59:1, 0x949992:1, 0x8C918A:1, 0x0277D3:1,
                0x037CD6:1, 0x076FC0:1, 0x0F4F8A:1, 0x233538:1, 0x263D30:1, 0x4B6B58:1, 0x283E32:1, 0x273D32:1, 0x273E31:1, 0x263A2E:1,
                0x25382B:1, 0x233728:1, 0x223427:1, 0x203026:1, 0x1F2F24:1, 0x1D2B21:1, 0x222C23:1, 0x959992:1, 0xA5A89F:1, 0xA8ABA2:1,
                0x949A91:1, 0x959A93:1, 0x5189AD:1, 0x0478CF:1, 0x4B6C5A:1, 0x0B4F93:1, 0x124C8D:1, 0x143E6C:1, 0x253B30:1, 0x243C30:1,
                0x3F554A:1, 0x4B6D5C:1, 0x253B2E:1, 0x263B2D:1, 0x263B2C:1, 0x24392B:1, 0x223929:1, 0x223728:1, 0x203025:1, 0x1D2C21:1,
                0x252F26:1, 0x4C6D5C:1, 0x9C9F98:1, 0xA1A49B:1, 0xA3A79D:1, 0x989D93:1, 0x919690:1, 0x8F948D:1, 0x187AC2:1, 0x095CA5:1,
                0x0C5297:1, 0x4C6E5D:1, 0x0D559C:1, 0x005A9E:1, 0x0377CE:1, 0x0B5398:1, 0x0D5399:1, 0x085FA1:1, 0x0474CB:1, 0x0B549B:1,
                0x0D5398:1, 0x0E539B:1, 0x366B92:1, 0x0276D3:1, 0x0379D2:1, 0x0A5CA6:1, 0x507060:1, 0x0E5297:1, 0x0E5298:1, 0x104F91:1,
                0x4F7060:1, 0x537162:1, 0x557364:1, 0x567062:1, 0x444E43:1, 0x41564B:1, 0x48443E:1, 0x54524D:1, 0x58544B:1, 0x5C564D:1,
                0x64584F:1, 0x78665C:1, 0x7A685F:1, 0x453E37:1, 0x3E3934:1, 0x302D29:1, 0x42584D:1, 0x2E322C:1, 0x456054:1, 0x48685A:1,
                0x476759:1, 0x41644E:1, 0x41644F:1, 0x426550:1, 0x43594E:1, 0x476955:1, 0x486957:1, 0x496957:1, 0x4A6B58:1, 0x4B6C5B:1,
                0x4C6C5C:1, 0x4E6D5E:1, 0x445A4F:1, 0x506D5E:1, 0x516D5F:1, 0x516E60:1, 0x516559:1, 0x37382D:1, 0x353126:1, 0x45433D:1,
                0x524944:1, 0x61544B:1, 0x715E52:1, 0x455A4F:1, 0x907967:1, 0xAB9280:1, 0x5D4E43:1, 0x312D27:1, 0x2F2E2A:1, 0x2D2D28:1,
                0x43574D:1, 0x496659:1, 0x476659:1, 0x456458:1, 0x455B50:1, 0x436256:1, 0x3A4C45:1, 0x717171:1, 0x727272:1, 0x456553:1,
                0x456755:1, 0x475C51:1, 0x466756:1, 0x496A58:1, 0x4B6B5C:1, 0x4B6B5B:1, 0x4A6A5A:1, 0x4E6B5D:1, 0x4F6C5E:1, 0x4A5D51:1,
                0x475D51:1, 0x2D2B20:1, 0x2F291E:1, 0x332D26:1, 0x4B403A:1, 0x635247:1, 0x7D6759:1, 0x9E8470:1, 0xCAAC98:1, 0x89776A:1,
                0x2D2923:1, 0x475E52:1, 0x2B2D27:1, 0x415148:1, 0x4A6559:1, 0x466559:1, 0x446256:1, 0x436155:1, 0x436054:1, 0x3A4C44:1,
                0x3F614E:1, 0x42624E:1, 0x43644F:1, 0x426451:1, 0x446654:1, 0x496959:1, 0x485E53:1, 0x4B695A:1, 0x404D43:1, 0x2B271C:1,
                0x54483C:1, 0x615044:1, 0x735A4D:1, 0x7D6151:1, 0x886D5D:1, 0x997D69:1, 0xC2A48D:1, 0x495E53:1, 0xB29B8A:1, 0x423C34:1,
                0x24231F:1, 0x3D483F:1, 0x4A6157:1, 0x425F53:1, 0x2F2F2F:1, 0x4B5F54:1, 0x3E5E4F:1, 0x3D5F4D:1, 0x3D5F4C:1, 0x3F604E:1,
                0x40614E:1, 0x426250:1, 0x42624F:1, 0x436554:1, 0x4B6055:1, 0x466556:1, 0x496657:1, 0x3A4035:1, 0x65594C:1, 0x816F5C:1,
                0x725D48:1, 0xA38471:1, 0xCDAA96:1, 0x957461:1, 0x4C6256:1, 0x7B5C49:1, 0xA6836E:1, 0xD7B49F:1, 0x7B695E:1, 0x24231B:1,
                0x25261F:1, 0x383F37:1, 0x485D53:1, 0x416053:1, 0x425E51:1, 0x545454:1, 0x4D6156:1, 0x425E50:1, 0x415E51:1, 0x384B43:1,
                0x626262:1, 0x3D5D4D:1, 0x3D5D4C:1, 0x4D6256:1, 0x3F5F4D:1, 0x3E5F4D:1, 0x3F5F4E:1, 0x40604E:1, 0x476456:1, 0x496255:1,
                0x33362D:1, 0x988578:1, 0x4E6056:1, 0xCEB19B:1, 0xAD9076:1, 0xD5B39D:1, 0xEECBB4:1, 0xD0AA94:1, 0xB6937D:1, 0xE2BCA7:1,
                0xEDC3AC:1, 0x988174:1, 0x25241E:1, 0x4F5851:1, 0x22231C:1, 0x30362F:1, 0x465950:1, 0x425D51:1, 0x3C5A4B:1, 0x3E5B4C:1,
                0x405B4D:1, 0x3F413C:1, 0x3F5C4E:1, 0x3F6050:1, 0x436052:1, 0x465A4E:1, 0x2D2D26:1, 0x7D695B:1, 0xDBB89F:1, 0xDFBCA0:1,
                0xDFBBA1:1, 0xEDC9AE:1, 0xE6BCA3:1, 0xEAC4A9:1, 0xE7BFA7:1, 0xCEA991:1, 0x837060:1, 0x25231F:1, 0x20211A:1, 0x3F3E3A:1,
                0x242A23:1, 0x3F5148:1, 0x435A50:1, 0x3D5D4E:1, 0x384A41:1, 0x3B5A4A:1, 0x3B5A4B:1, 0x3C5A4C:1, 0x3F5B4F:1, 0x3E3D39:1,
                0x3D5C4F:1, 0x415F52:1, 0x406051:1, 0x3F5E50:1, 0x426153:1, 0x426254:1, 0x3D5D50:1, 0x405D4E:1, 0x445248:1, 0x363531:1,
                0x473B2C:1, 0xB19178:1, 0xCBA78B:1, 0xB59076:1, 0xAB856B:1, 0xC0967D:1, 0xCAA388:1, 0xC7A085:1, 0xB08C75:1, 0x6E5D4E:1,
                0x41423E:1, 0x22201C:1, 0x21221B:1, 0x23241E:1, 0x2E3B34:1, 0x435A4F:1, 0x405C50:1, 0x374941:1, 0x5C7B71:1, 0x517369:1,
                0x474747:1, 0x3C433F:1, 0x4C7068:1, 0x557369:1, 0x4B6B61:1, 0x52716B:1, 0x5B7B76:1, 0x4E7068:1, 0x4F7168:1, 0x4A6D64:1,
                0x47574F:1, 0x56786F:1, 0x5A7D73:1, 0x5C7F75:1, 0x4B6C62:1, 0x4E6C5F:1, 0x405B4E:1, 0x415A4C:1, 0x3F4941:1, 0x455850:1,
                0x231D11:1, 0x836654:1, 0xB6947B:1, 0xC49E8A:1, 0xBD9685:1, 0xD5AE99:1, 0xBE9C81:1, 0xB49376:1, 0x9F8268:1, 0x55483A:1,
                0x455851:1, 0x221C16:1, 0x262420:1, 0x252621:1, 0x232A24:1, 0x3E5148:1, 0x374841:1, 0x737373:1, 0x747474:1, 0x4D6C67:1,
                0x445850:1, 0x4F716C:1, 0x597E7A:1, 0x567A74:1, 0x45655B:1, 0x4B6B60:1, 0x46665F:1, 0x587773:1, 0x60817D:1, 0x51736D:1,
                0x567871:1, 0x43564E:1, 0x3E605A:1, 0x5B7D76:1, 0x507169:1, 0x4D6E68:1, 0x4F6E63:1, 0x445D50:1, 0x40584A:1, 0x41574B:1,
                0x394139:1, 0x282820:1, 0x41564D:1, 0x1C1812:1, 0x3D2B20:1, 0x937760:1, 0x916C59:1, 0x8F6558:1, 0x9C7564:1, 0xB08E77:1,
                0xA4846D:1, 0x826B58:1, 0x332B22:1, 0x3E544B:1, 0x241F19:1, 0x2B2825:1, 0x2C2C27:1, 0x272A25:1, 0x313A34:1, 0x41554A:1,
                0x3F584B:1, 0x3E584B:1, 0x36463F:1, 0x3E5C54:1, 0x39403D:1, 0x3E5E58:1, 0x416159:1, 0x3D5950:1, 0x405D53:1, 0x3D5A50:1,
                0x46635A:1, 0x48665E:1, 0x3E5D53:1, 0x3F5E53:1, 0x3A584F:1, 0x425F55:1, 0x415C51:1, 0x3F5C51:1, 0x3F5D51:1, 0x415448:1,
                0x383E36:1, 0x1C1B16:1, 0x151412:1, 0x493B2D:1, 0x93715E:1, 0x9D7462:1, 0xA47C69:1, 0xA38269:1, 0x866C55:1, 0x48392E:1,
                0x1F1C1C:1, 0x262724:1, 0x333430:1, 0x393A35:1, 0x343631:1, 0x2E312C:1, 0x3C473F:1, 0x3F5549:1, 0x3D5549:1, 0x36453E:1,
                0x292929:1, 0x3C5545:1, 0x3E5647:1, 0x456655:1, 0x3F5548:1, 0x3F5649:1, 0x3E574A:1, 0x3C5749:1, 0x3B5647:1, 0x3B5545:1,
                0x3E5244:1, 0x466857:1, 0x383E34:1, 0x2A2A21:1, 0x1F1E18:1, 0x161512:1, 0x17140F:1, 0x635045:1, 0x8D735F:1, 0x907660:1,
                0x77624F:1, 0x3E3327:1, 0x191614:1, 0x222222:1, 0x2E2E2A:1, 0x3D3D39:1, 0x373732:1, 0x363D36:1, 0x3F5249:1, 0x3D544A:1,
                0x35443E:1, 0x282828:1, 0x3A5445:1, 0x3A5444:1, 0x3B5443:1, 0x3B5444:1, 0x486B59:1, 0x3F5144:1, 0x3A3D36:1, 0x2C2922:1,
                0x25221C:1, 0x171713:1, 0x0F100D:1, 0x15120F:1, 0x2E2920:1, 0x322E25:1, 0x201B16:1, 0x496C5A:1, 0x101111:1, 0x18181C:1,
                0x2D2C29:1, 0x373632:1, 0x393834:1, 0x3D3B37:1, 0x3C3B37:1, 0x3A3834:1, 0x383A35:1, 0x3E4D45:1, 0x3B5146:1, 0x33433B:1,
                0x375241:1, 0x385240:1, 0x3A523F:1, 0x3B5341:1, 0x3B5342:1, 0x3B5343:1, 0x395241:1, 0x395341:1, 0x3A5242:1, 0x3E4F42:1,
                0x383A33:1, 0x507160:1, 0x2D2A24:1, 0x2A2722:1, 0x191915:1, 0x121310:1, 0x0E100D:1, 0x0C100A:1, 0x0B100B:1, 0x0C110F:1,
                0x101212:1, 0x232422:1, 0x50725F:1, 0x34332F:1, 0x383733:1, 0x585756:1, 0xB4B4B1:1, 0xC2C1BF:1, 0x757472:1, 0x3C3D39:1,
                0x3D4A41:1, 0x394F44:1, 0x32423A:1, 0x365240:1, 0x37503F:1, 0x37513D:1, 0x37523F:1, 0x39523E:1, 0x385340:1, 0x38523E:1,
                0x527361:1, 0x384F3E:1, 0x354539:1, 0x33352E:1, 0x2F2F28:1, 0x282822:1, 0x1E1F1C:1, 0x151515:1, 0x151714:1, 0x0D120E:1,
                0x0C110E:1, 0x537563:1, 0x0D1110:1, 0x171A19:1, 0x2E302C:1, 0x52514D:1, 0xDCDBDC:1, 0xFBFBFB:1, 0xFCFCFC:1, 0xF1F0F0:1,
                0x898A88:1, 0x424F45:1, 0x547564:1, 0x384E43:1, 0x38503F:1, 0x38513D:1, 0x557564:1, 0x39513F:1, 0x385040:1, 0x36473C:1,
                0x3B443C:1, 0x333730:1, 0x25231D:1, 0x282521:1, 0x1A1A18:1, 0x547764:1, 0x131512:1, 0x0F110E:1, 0x0E120F:1, 0x151816:1,
                0x30302C:1, 0x63625E:1, 0xDBDAD6:1, 0xFBF9FA:1, 0xF5F5F5:1, 0x848B86:1, 0x557765:1, 0x3A4D44:1, 0x262626:1, 0x364E3F:1,
                0x36503E:1, 0x36503D:1, 0x567666:1, 0x364C40:1, 0x35483D:1, 0x36463C:1, 0x373C36:1, 0x282620:1, 0x25231C:1, 0x1F1F1B:1,
                0x141613:1, 0x11130F:1, 0x121511:1, 0x577766:1, 0x1E201D:1, 0x272722:1, 0x545350:1, 0xD5D4D1:1, 0xF9F8F6:1, 0xFDFCFB:1,
                0x94DDF6:1, 0x4CCAEA:1, 0x33C3E4:1, 0x32C3DE:1, 0x597968:1, 0x31C3DD:1, 0x31C5D7:1, 0x34C8CE:1, 0x39C9C5:1, 0x38BBB3:1,
                0x359388:1, 0x293734:1, 0x374E40:1, 0x364F3F:1, 0x35503F:1, 0x5C7B6B:1, 0x374E3F:1, 0x384F40:1, 0x374F41:1, 0x354B3F:1,
                0x32463A:1, 0x48534A:1, 0x494843:1, 0x23221A:1, 0x5D7B6C:1, 0x1D1D16:1, 0x151611:1, 0x141612:1, 0x1A1C17:1, 0x21231E:1,
                0x393B36:1, 0xCDCDCA:1, 0xFBFAF8:1, 0xA5E1F8:1, 0x36C1F0:1, 0x5D7A6B:1, 0x34C0EF:1, 0x32C1E7:1, 0x30C2DE:1, 0x30C5D5:1,
                0x30C5D2:1, 0x36CACA:1, 0x38CCC5:1, 0x3FD1B9:1, 0x5D6F64:1, 0x46D7AD:1, 0x354C41:1, 0x354C40:1, 0x354D3F:1, 0x384E44:1,
                0x3F564D:1, 0x3D5449:1, 0x334C41:1, 0x344E42:1, 0x364F42:1, 0x60625C:1, 0x344C40:1, 0x344C3E:1, 0x354C3E:1, 0x354D40:1,
                0x354C3F:1, 0x304538:1, 0x2F4135:1, 0x636C64:1, 0x504E49:1, 0xA4A6A0:1, 0x282823:1, 0x191B16:1, 0x161715:1, 0x1A1B18:1,
                0x262722:1, 0x555650:1, 0xD7D7D3:1, 0xF1F2ED:1, 0x494742:1, 0x35C0F4:1, 0x34C0F0:1, 0x32C1EB:1, 0x32C1E8:1, 0x2DC4D2:1,
                0x2FC5D0:1, 0x34C9C8:1, 0x37CBC3:1, 0x3CCFBE:1, 0x3E3B36:1, 0x45D6AE:1, 0x566F6A:1, 0x506B66:1, 0x54706A:1, 0x4D675F:1,
                0x485E56:1, 0x435A53:1, 0x48615D:1, 0x4C6664:1, 0x496462:1, 0x343434:1, 0x4D4842:1, 0x506D6A:1, 0x4C6663:1, 0x485F55:1,
                0x334B3E:1, 0x32493C:1, 0x2D4236:1, 0x2D3E33:1, 0x53504A:1, 0x767D76:1, 0xC6C9BF:1, 0x2B2D24:1, 0x292924:1, 0x1D1E1A:1,
                0x2D2D2B:1, 0x878582:1, 0xE4E1DE:1, 0x4F4C47:1, 0x34C0F2:1, 0x32C0EC:1, 0x30C1E3:1, 0x2FC1DF:1, 0x2CC3D2:1, 0x2EC5CE:1,
                0x32C8CA:1, 0x36CBC5:1, 0x3CCFB8:1, 0x435F5B:1, 0x516F6C:1, 0x76928F:1, 0x627C77:1, 0x48605B:1, 0x465E59:1, 0x57716E:1,
                0x486565:1, 0x34342F:1, 0x5F7D7F:1, 0x6F8D93:1, 0x678389:1, 0x617A76:1, 0x374E42:1, 0x30493B:1, 0x2F4739:1, 0x2E4536:1,
                0x2D4237:1, 0x46594F:1, 0x2E3C33:1, 0x91958E:1, 0x9FA296:1, 0x63655A:1, 0x9D9D98:1, 0x8C8C85:1, 0xD5D3D1:1, 0xF6F3F1:1,
                0xFEFBF9:1, 0x516D61:1, 0x52C7FA:1, 0x35BFF7:1, 0x33C0F1:1, 0x32C0ED:1, 0x2FC1E0:1, 0x2CC2DA:1, 0x2BC2D6:1, 0x2CC4D0:1,
                0x30C7C9:1, 0x4F6D61:1, 0x34CAC4:1, 0x36CBBF:1, 0x364C43:1, 0x39524B:1, 0x415852:1, 0x40554D:1, 0x364B42:1, 0x4C6159:1,
                0x475A53:1, 0x51635B:1, 0x4E6D61:1, 0x49584F:1, 0x5D6762:1, 0x707A75:1, 0x55665F:1, 0x475D50:1, 0x32483C:1, 0x30463A:1,
                0x2D4336:1, 0x4C6B5E:1, 0x324037:1, 0xD2D4CE:1, 0xF3F3E9:1, 0xE5E5DD:1, 0xF8F5F2:1, 0xFAFAF1:1, 0xFBFAF3:1, 0xFDFCF6:1,
                0xA5E1F9:1, 0x34BFF8:1, 0x34BFF6:1, 0x33C0F3:1, 0x31C0EE:1, 0x2BB7E3:1, 0x28B3DD:1, 0x2AB8DC:1, 0x2CC2D8:1, 0x2BC3D1:1,
                0x2FC5CA:1, 0x49685B:1, 0x33C8C3:1, 0x37CBBB:1, 0x43D3A9:1, 0x32493B:1, 0x33483B:1, 0x35493D:1, 0x48544D:1, 0x676359:1,
                0x796A5D:1, 0xA38C7C:1, 0x3C5147:1, 0xBC9789:1, 0xE3C4B3:1, 0xE5D9C5:1, 0xABAD99:1, 0x505B50:1, 0x2E4339:1, 0x414E45:1,
                0xF3F4EF:1, 0xF8F5F3:1, 0xFBFAF5:1, 0xFBFBF6:1, 0xFDFCF7:1, 0x35BEF8:1, 0x33C0F8:1, 0x2DB5EE:1, 0x1C96D3:1, 0x1280C1:1,
                0x1181C2:1, 0x1282C3:1, 0x1482C1:1, 0x1684BE:1, 0x1E9AC5:1, 0x27B9D1:1, 0x2FC5C8:1, 0x35C9BB:1, 0x3FD0A9:1, 0x436553:1,
                0x31493A:1, 0x314937:1, 0x304937:1, 0x324839:1, 0x555D51:1, 0x9F8978:1, 0xC49A88:1, 0xE1B6A1:1, 0xCF9F89:1, 0xD7A892:1,
                0xF3D5BE:1, 0xFBF0D4:1, 0xD5D2B9:1, 0x686F5F:1, 0x2F4336:1, 0x2C4034:1, 0x2C3E34:1, 0x858A84:1, 0xFCFCF9:1, 0xFDFCFC:1,
                0x466956:1, 0xFEFCFD:1, 0xFDFAFB:1, 0xFDFBFB:1, 0x93DCF9:1, 0x34BFFA:1, 0x1F9DDE:1, 0x0D7DC6:1, 0x0E83CE:1, 0x0F88D3:1,
                0x118AD4:1, 0x128DD5:1, 0x148FD5:1, 0x158ED2:1, 0x168ACA:1, 0x1683BF:1, 0x1F9FC6:1, 0x2FC5C5:1, 0x32C7C0:1, 0x36CABB:1,
                0x3ECFAB:1, 0x496A57:1, 0x31463B:1, 0x304839:1, 0x2E4635:1, 0x2E4736:1, 0x30473A:1, 0x2E4035:1, 0x403D31:1, 0xA78370:1,
                0xDCB29B:1, 0xFCDFC3:1 }

    if MultiPixelSearch(X1, Y1, X2, Y2, Colors)
        MsgBox "found"
    else
        MsgBox "not found"           
}

Return to “Scripts and Functions (v2)”