Jump to content

nPixelSearch / BmpSearchColor


wolf9228
 Share

Recommended Posts

ColorSearch.au3

#include <WinAPI.au3>
#include <Memory.au3>
#include <Color.au3>
#include <ScreenCapture.au3>

Global $itagRGBQUAD = "BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved"
Global $RgbSize = DllStructGetSize(DllStructCreate($itagRGBQUAD))

$Pos1 = nPixelSearch(0, 0, @DesktopWidth, @DesktopHeight,0xFFFFFF) ;0xFFFFFF White Color
$Pos2 = PixelSearch(0 , 0, @DesktopWidth, @DesktopHeight,0xFFFFFF) ;0xFFFFFF White Color

if IsArray($Pos1) And IsArray($Pos2) Then
$Text1 = String($Pos1[0] & "  " & $Pos1[1])
$Text2 = String($Pos2[0] & "  " & $Pos2[1])
MsgBox(0,"PixelSearch",$Text1 & @CRLF & $Text2)
EndIf


Func nPixelSearch($left = 0,$top = 0,$right = -1,$bottom = -1,$Color = 0,$bCursor = False)
Local $hBmp = _ScreenCapture_Capture("",$left,$top,$right,$bottom,$bCursor)
if Not($hBmp) Then Return SetError(1,0,0)
Local $aCoord = BmpSearchColor($hBmp,$Color)
_WinAPI_DeleteObject($hBmp)
if Not IsArray($aCoord) Then Return SetError(2,0,0)
Return $aCoord
EndFunc

Func BmpSearchColor($hBmp,$Color)
Local $BitsStruct = GetBitsStruct($hBmp)
if @error Then Return SetError(1,0,0)
Local $BitsPtr = DllStructGetPtr($BitsStruct,"RGBQUAD")
Local $BitsSize = DllStructGetData($BitsStruct,"SIZE")
Local $biWidth = DllStructGetData($BitsStruct,"WIDTH")
Local $biHeight = DllStructGetData($BitsStruct,"HEIGHT")
Local $iColor = DllStructCreate("BYTE RGB[3]")
DllStructSetData($iColor,1,$Color)
$iColorPtr = DllStructGetPtr($iColor)
For $i = 0 To ($BitsSize - 4) Step 4
$Return = DllCall("Msvcrt.dll","int:cdecl","memcmp","ptr",$BitsPtr + $i,"ptr",$iColorPtr,"int",3)
if @error Then
ExitLoop
Else
if $Return[0] = 0 Then ExitLoop
EndIf
Next
if @error Or $Return[0] <> 0 Then Return SetError(2,0,0)
$position = ($i) ;position
$position /= $RgbSize ; $RgbSize = 4 /// 4byte = 1pixel
$X =  Mod($position,$biWidth) ; Get left
$Y = (($position - $X) / $biWidth) ; Get top
Local $aCoord[2]
$aCoord[0] = $X
$aCoord[1] = $Y
Return $aCoord
EndFunc

Func GetBitsStruct( $hBmp , $L = -1 , $T = -1 , $W = -1 , $H = -1 )
Local $SizeArray = GetImageSize($hBmp)
if @error Then Return SetError(1,0,0)
Local $biWidth = $SizeArray[0]
Local $biHeight = $SizeArray[1]
if ($L < 0) Then $L = 0
if ($T < 0) Then $T = 0
if ($W < 0) Then $W = ($biWidth - $L)
if ($H < 0) Then $H = ($biHeight - $T)
if ($L >= $biWidth Or (($L + $W) > $biWidth)) Then $L = 0
if ($T >= $biHeight Or (($T + $H) > $biHeight)) Then $T = 0
Local $vRgbSize = ($RgbSize * ($biWidth * $biHeight))
Local $vStBits = DllStructCreate("INT WIDTH;INT HEIGHT;INT SIZE;BYTE RGBQUAD[" & ($vRgbSize) & "]")
DllStructSetData($vStBits ,"WIDTH",$biWidth)
DllStructSetData($vStBits,"HEIGHT",$biHeight)
DllStructSetData($vStBits,"SIZE",$vRgbSize)
GetBitmapBits($hBmp,DllStructGetPtr($vStBits,"RGBQUAD"),$vRgbSize)
if @error Then Return SetError(2,0,0)
if ($L = 0 And $T = 0 And $W = $biWidth And $H = $biHeight) Then Return $vStBits
Local $nRgbSize = ($RgbSize * ($W * $H)) , $ColusCount = $W
Local $nStBits = DllStructCreate("INT WIDTH;INT HEIGHT;INT SIZE;BYTE RGBQUAD[" & ($nRgbSize) & "]")
DllStructSetData($nStBits ,"WIDTH",$W)
DllStructSetData($nStBits,"HEIGHT",$H)
DllStructSetData($nStBits,"SIZE",$nRgbSize)
For $RowIndex = 0 To ($H - 1)
Local $nStBPtr = GetPointerAtRowPos($nStBits,$RowIndex)
; Move Ptr To First BYTE Of Row => $RowIndex
Local $vStBPtr = GetPointerAtRowPos($vStBits,($RowIndex + $T)) + ($L * $RgbSize)
; Move Ptr To First BYTE Of Row => ($RowIndex + $T)
; + ($L * $RgbSize) Move PointerAtRowPos From left to right + ($L * $RgbSize)
_MemMoveMemory($vStBPtr,$nStBPtr,($RgbSize * ($ColusCount - 1))) ;Size Of One Row In $nStBPtr
Next
Return $nStBits
EndFunc

Func GetBitmapBits($hbmp,$lpvBits,$cbBuffer)
$BytesNu = DllCall("Gdi32.dll","LONG","GetBitmapBits","ptr" _
,$hbmp,"LONG",$cbBuffer,"ptr",$lpvBits)
if @error Or Not($BytesNu[0]) Then SetError(1,0,0)
Return SetError(0,0,$BytesNu[0])
EndFunc

Func GetPointerAtRowPos($StBits,$RowIndex)
if Not IsDllStruct($StBits) Then Return SetError(1,0,0)
Local $ColusCount = DllStructGetData($StBits,"WIDTH")
Local $RowsCount = DllStructGetData($StBits,"HEIGHT")
If ($RowIndex < 0 Or $RowIndex > ($RowsCount -1)) Then Return SetError(2,0,0)
Local $StBitsPtr = DllStructGetPtr($StBits,"RGBQUAD")
Local $PointerAtRowPos = ($StBitsPtr + (($RowIndex * $ColusCount) * $RgbSize))
Return $PointerAtRowPos
EndFunc

Func GetImageSize($hBmp)
Local $ntagBITMAPINFO = "DWORD biSize;LONG biWidth;LONG biHeight;USHORT biPlanes;" & _
"USHORT biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;" & _
"LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;BYTE RGBQUAD[4]"
Local $vBITMAPINFO = DllStructCreate($ntagBITMAPINFO)
DllStructSetData($vBITMAPINFO,"biSize",(DllStructGetSize($vBITMAPINFO) - $RgbSize))
Local $hDC = _WinAPI_CreateCompatibleDC(0)
if Not($hDC) Then
_WinAPI_DeleteDC($hDC)
Return SetError(1,0,0)
EndIf
$Return = _WinAPI_GetDIBits($hDC,$hBmp,0,0,0,DllStructGetPtr($vBITMAPINFO),0)
if Not($Return) Then
_WinAPI_DeleteDC($hDC)
Return SetError(2,0,0)
EndIf
_WinAPI_DeleteDC($hDC)
Local $biWidth = DllStructGetData($vBITMAPINFO,"biWidth")
Local $biHeight = DllStructGetData($vBITMAPINFO,"biHeight")
Local $SizeArray[2]
$SizeArray[0] = $biWidth
$SizeArray[1] = $biHeight
Return $SizeArray
EndFunc
Edited by wolf9228

صرح السماء كان هنا

 

Link to comment
Share on other sites

Save function using C++ language
Started by wolf9228, Jan 09 2013 08:51 AM
'?do=embed' frameborder='0' data-embedContent>>

Other ColorSearch.au3

#include <WinAPI.au3>
#include <Memory.au3>
#include <Color.au3>
#include <ScreenCapture.au3>
Global $itagRGBQUAD = "BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved"
Global $RgbSize = DllStructGetSize(DllStructCreate($itagRGBQUAD))
Global $memcmp = _WinAPI_GetProcAddress (_WinAPI_LoadLibrary("Msvcrt.dll"),"memcmp")


$hTimer = TimerInit()
$Pos1 = nPixelSearch(0, 0, @DesktopWidth, @DesktopHeight,0xFFFFFF) ;0xFFFFFF Color White
$iDiff1 = TimerDiff($hTimer)
$hTimer = TimerInit()
$Pos2 = PixelSearch(0 , 0, @DesktopWidth, @DesktopHeight,0xFFFFFF) ;0xFFFFFF Color White
$iDiff2 = TimerDiff($hTimer)
if IsArray($Pos1) And IsArray($Pos2) Then
$Text1 = String($Pos1[0] & "  " & $Pos1[1] & " nPixelSearch Time ==> " & $iDiff1)
$Text2 = String($Pos2[0] & "  " & $Pos2[1] & " PixelSearch Time  ==> " & $iDiff2)
MsgBox(0,"PixelSearch",$Text1 & @CRLF & $Text2)
EndIf


Func nPixelSearch($left = 0,$top = 0,$right = -1,$bottom = -1,$Color = 0,$bCursor = False)
Local $hBmp = _ScreenCapture_Capture("",$left,$top,$right,$bottom,$bCursor)
if Not($hBmp) Then Return SetError(1,0,0)
Local $aCoord = BmpSearchColor($hBmp,$Color)
_WinAPI_DeleteObject($hBmp)
if Not IsArray($aCoord) Then Return SetError(2,0,0)
Return $aCoord
EndFunc

Func SearchBinary($key,$base,$num,$width,$Step = 1)
;int WINAPI SearchBinary(BYTE* key,BYTE* base,int num,int width,int Step,void* icompare)
;int WINAPI SearchBinary(BYTE* key,BYTE* base,int num,int width,int Step,void* icompare)
;{

;typedef int ( __cdecl *compare ) (void*,void*,size_t);
;compare vcompare = (compare) icompare;

;for (int i = 0; i <= (num - Step); i+= Step)
;if (vcompare(key,(base + i),width) == 0) return i;

;return -1;

;}
$BytesStr = ""
$BytesStr &= "0x558BEC5356578B75188B7D1C33DBEB1BFF75148B450C03C350FF7508FFD783C40C85C075048BC3"
$BytesStr &= "EB0E03DE8B55102BD63BDA7EDC83C8FF5F5E5B5DC218009090"
$SearchBinary = DllStructCreate("byte[" & BinaryLen($BytesStr) & "]")
DllStructSetData($SearchBinary,1,$BytesStr)
$Address = DllStructGetPtr($SearchBinary)
$Return = DllCallAddress("int",$Address,"ptr",$key,"ptr",$base,"int",$num,"int",$width,"int",$Step,"ptr",$memcmp)
if @error Or $Return[0] = -1 Then Return SetError(1,0,0)
Return $Return[0]
EndFunc

Func BmpSearchColor($hBmp,$Color)
Local $BitsStruct = GetBitsStruct($hBmp)
if @error Then Return SetError(1,0,0)
Local $BitsPtr = DllStructGetPtr($BitsStruct,"RGBQUAD")
Local $BitsSize = DllStructGetData($BitsStruct,"SIZE")
Local $biWidth = DllStructGetData($BitsStruct,"WIDTH")
Local $biHeight = DllStructGetData($BitsStruct,"HEIGHT")
Local $iColor = DllStructCreate("BYTE RGB[3]")
DllStructSetData($iColor,1,$Color)
$iColorPtr = DllStructGetPtr($iColor)
$position = SearchBinary($iColorPtr,$BitsPtr,$BitsSize,3,4) ; width 3 //step 4
if @error Then Return SetError(2,0,0)
$position /= $RgbSize ; $RgbSize = 4 /// 4byte = 1pixel
$X =  Mod($position,$biWidth) ; Get left
$Y = (($position - $X) / $biWidth) ; Get top
Local $aCoord[2]
$aCoord[0] = $X
$aCoord[1] = $Y
Return $aCoord
EndFunc

Func GetBitsStruct( $hBmp , $L = -1 , $T = -1 , $W = -1 , $H = -1 )
Local $SizeArray = GetImageSize($hBmp)
if @error Then Return SetError(1,0,0)
Local $biWidth = $SizeArray[0]
Local $biHeight = $SizeArray[1]
if ($L < 0) Then $L = 0
if ($T < 0) Then $T = 0
if ($W < 0) Then $W = ($biWidth - $L)
if ($H < 0) Then $H = ($biHeight - $T)
if ($L >= $biWidth Or (($L + $W) > $biWidth)) Then $L = 0
if ($T >= $biHeight Or (($T + $H) > $biHeight)) Then $T = 0
Local $vRgbSize = ($RgbSize * ($biWidth * $biHeight))
Local $vStBits = DllStructCreate("INT WIDTH;INT HEIGHT;INT SIZE;BYTE RGBQUAD[" & ($vRgbSize) & "]")
DllStructSetData($vStBits ,"WIDTH",$biWidth)
DllStructSetData($vStBits,"HEIGHT",$biHeight)
DllStructSetData($vStBits,"SIZE",$vRgbSize)
GetBitmapBits($hBmp,DllStructGetPtr($vStBits,"RGBQUAD"),$vRgbSize)
if @error Then Return SetError(2,0,0)
if ($L = 0 And $T = 0 And $W = $biWidth And $H = $biHeight) Then Return $vStBits
Local $nRgbSize = ($RgbSize * ($W * $H)) , $ColusCount = $W
Local $nStBits = DllStructCreate("INT WIDTH;INT HEIGHT;INT SIZE;BYTE RGBQUAD[" & ($nRgbSize) & "]")
DllStructSetData($nStBits ,"WIDTH",$W)
DllStructSetData($nStBits,"HEIGHT",$H)
DllStructSetData($nStBits,"SIZE",$nRgbSize)
For $RowIndex = 0 To ($H - 1)
Local $nStBPtr = GetPointerAtRowPos($nStBits,$RowIndex)
; Move Ptr To First BYTE Of Row => $RowIndex
Local $vStBPtr = GetPointerAtRowPos($vStBits,($RowIndex + $T)) + ($L * $RgbSize)
; Move Ptr To First BYTE Of Row => ($RowIndex + $T)
; + ($L * $RgbSize) Move PointerAtRowPos From left to right + ($L * $RgbSize)
_MemMoveMemory($vStBPtr,$nStBPtr,($RgbSize * ($ColusCount - 1))) ;Size Of One Row In $nStBPtr
Next
Return $nStBits
EndFunc

Func GetBitmapBits($hbmp,$lpvBits,$cbBuffer)
$BytesNu = DllCall("Gdi32.dll","LONG","GetBitmapBits","ptr" _
,$hbmp,"LONG",$cbBuffer,"ptr",$lpvBits)
if @error Or Not($BytesNu[0]) Then SetError(1,0,0)
Return SetError(0,0,$BytesNu[0])
EndFunc

Func GetPointerAtRowPos($StBits,$RowIndex)
if Not IsDllStruct($StBits) Then Return SetError(1,0,0)
Local $ColusCount = DllStructGetData($StBits,"WIDTH")
Local $RowsCount = DllStructGetData($StBits,"HEIGHT")
If ($RowIndex < 0 Or $RowIndex > ($RowsCount -1)) Then Return SetError(2,0,0)
Local $StBitsPtr = DllStructGetPtr($StBits,"RGBQUAD")
Local $PointerAtRowPos = ($StBitsPtr + (($RowIndex * $ColusCount) * $RgbSize))
Return $PointerAtRowPos
EndFunc

Func GetImageSize($hBmp)
Local $ntagBITMAPINFO = "DWORD biSize;LONG biWidth;LONG biHeight;USHORT biPlanes;" & _
"USHORT biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;" & _
"LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;BYTE RGBQUAD[4]"
Local $vBITMAPINFO = DllStructCreate($ntagBITMAPINFO)
DllStructSetData($vBITMAPINFO,"biSize",(DllStructGetSize($vBITMAPINFO) - $RgbSize))
Local $hDC = _WinAPI_CreateCompatibleDC(0)
if Not($hDC) Then
_WinAPI_DeleteDC($hDC)
Return SetError(1,0,0)
EndIf
$Return = _WinAPI_GetDIBits($hDC,$hBmp,0,0,0,DllStructGetPtr($vBITMAPINFO),0)
if Not($Return) Then
_WinAPI_DeleteDC($hDC)
Return SetError(2,0,0)
EndIf
_WinAPI_DeleteDC($hDC)
Local $biWidth = DllStructGetData($vBITMAPINFO,"biWidth")
Local $biHeight = DllStructGetData($vBITMAPINFO,"biHeight")
Local $SizeArray[2]
$SizeArray[0] = $biWidth
$SizeArray[1] = $biHeight
Return $SizeArray
EndFunc
Edited by wolf9228

صرح السماء كان هنا

 

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