.
Instead of searching for a particular pixel,it searches for the pixel in the context of nearby pixels,It's my goto for pixel related stuff...& It's magnitudes faster than image search, & more reliable than plain pixel search.
Code: Select all
;___________________________________________
;GetMatrix(StartX,StartY,Dimension)
;FindMatrix(ScanStartX,ScanEndX,ScanStartY,ScanEndY,Dimension,Matrix)
;___________________________________________
;Tip : For faster searching, make sure the first pixel of matrix is
; not abundant on the screen
start:
;example of 9x9 matrix
SetBatchLines, -1
CoordMode, Pixel, Screen
CoordMode, Mouse, Screen
SplashImage,, W185 H50 B1, Press F4 to grab Matrix at mouse position,,
KeyWait, F4, D
MouseGetPos, mX, mY
SplashImage, Off
Matrix := GetMatrix(mX,mY,32)
TrayTip, MATRIX, MATRIX: %matrix%
Result := _FindMatrix(1,A_ScreenWidth,1,A_ScreenHeight,32,Matrix)
ToolTip, %Result%
StringSplit, Result, Result, %A_Space%
Loop, 5
{
SplashImage,, X%Result1% Y%Result2% W3 H3 B1 CWRed, .
Sleep, 500
SplashImage, Off
Sleep, 500
}
Goto, start
ExitApp
;___________________________________________
GetMatrix(StartX,StartY,Dimension)
{
Loop, %Dimension%
{
Loop, %Dimension%
{
PixelGetColor, Pix, %StartX%, %StartY%
Matrix = %Matrix%|%Pix%
StartX ++
}
StartY ++
StartX -= %Dimension%
}
StringTrimLeft, Matrix, Matrix, 1
Return %Matrix%
}
;___________________________________________
FindMatrix(ScanStartX,ScanEndX,ScanStartY,ScanEndY,Dimension,Matrix)
{
StringSplit, Pix, Matrix, |
Length := ScanEndY - ScanStartY
;loop for per line of screenY
Loop, %Length%
{
StartX = %ScanStartX%
EndX = %ScanEndX%
StartY := ScanStartY + A_Index - 1
EndY := ScanStartY + A_Index - 1
;loop for searching inside a line
Loop
{
count = 0
MatchFound = 1
;change variance and 'Fast' if not suited
PixelSearch, pX, pY, %StartX%, %StartY%, %EndX%, %EndY%, %Pix1%, 0, Fast
IfNotEqual, ERRORLEVEL, 0, Break
sX = %pX%
sY = %pY%
;loop for matching
Loop, %Dimension%
{
Loop, %Dimension%
{
Count ++
PixelGetColor, CurrPix, %pX%, %pY%
IfNotEqual, Pix%Count%, %CurrPix%
MatchFound = 0
IfEqual, MatchFound, 0, Break
pX ++
}
IfEqual, MatchFound, 0, Break
pY ++
pX -= %Dimension%
}
;match found!
IfEqual, MatchFound, 1
{
Result = %sX% %sY%
Return Result
}
StartX ++
DiffX := EndX - StartX
IfLess, DiffX, %Dimension%, Break
}
StartY ++
EndY ++
}
Return 0
}
;___________________________________________
/*
;The GetMatrix() function was very useful for me. I made a change so that it is able to search rectangular areas as well and wanted to share it in case anyone has a use for it.
GetMatrix(StartX, startY, DimensionX, DimensionY)
{
Loop, %DimensionY%
{
Loop, %DimensionX%
{
PixelGetColor, Pix, %StartX%, %StartY%
Matrix = %Matrix%|%Pix%
StartX ++
}
StartY ++
StartX -= %DimensionX%
}
StringTrimLeft, Matrix, Matrix, 1
Return %Matrix%
}
*/
/*
I'd identified an error (optimization really) that was causing some issues when the first pixel was not unique on the screen. After the 2 for loops that check the individual pixels, I updated StartX to the last X value returned by PixelSearch (plus one so it increments the loop).
With the original implementation I found PixelSearch was repeatedly returning the same pixel until the increment eventually caught up; which could be very wasteful in some cases :p.
For some people who are having trouble getting this to work on rectangular areas try the change below as well; I had one strange case where the function returned false negatives because the outer loop (length) was ending for some reason before the "line search" loop found the correct pixel.
*/
_FindMatrix(ScanStartX,ScanEndX,ScanStartY,ScanEndY,Dimension,Matrix)
{
StringSplit, Pix, Matrix, |
Length := ScanEndY - ScanStartY
pX = 0
pY = 0
;loop for per line of screenY
Loop, %Length%
{
StartX = %ScanStartX%
EndX = %ScanEndX%
StartY := ScanStartY + A_Index - 1
EndY := ScanStartY + A_Index - 1
;loop for searching inside a line
Loop
{
count = 0
MatchFound = 1
;change variance and 'Fast' if not suited
PixelSearch, pX, pY, %StartX%, %StartY%, %EndX%, %EndY%, %Pix1%, 0, Fast
IfNotEqual, ERRORLEVEL, 0, Break
sX = %pX%
sY = %pY%
;loop for matching
Loop, %Dimension%
{
Loop, %Dimension%
{
Count ++
PixelGetColor, CurrPix, %pX%, %pY%
IfNotEqual, Pix%Count%, %CurrPix%
MatchFound = 0
IfEqual, MatchFound, 0, Break
pX ++
}
IfEqual, MatchFound, 0, Break
pY ++
pX -= %Dimension%
}
;match found!
IfEqual, MatchFound, 1
{
Result = %sX% %sY%
Return Result
}
StartX := px + 1
DiffX := EndX - StartX
IfLess, DiffX, %Dimension%, Break
}
StartY ++
EndY ++
}
Return 0
}