MaximusCZ Posted November 13, 2018 Share Posted November 13, 2018 Hello, When I use _ScreenCapture_Capture, I get handle I can work with. Using that handle I can save image to disk with _ScreenCapture_SaveImage. How to load saved image so I get the handle of it again? I tried file read, file open, gdiplus bitmapcreate from file but nothing works. I found in help the way: capture, use gdiplusBitmapCreateFromHBITMAP, gdiplusImageSaveToFile, and then gdiplusBitmapCreateFromFile, but isnt there a way to load and get handle of saved bmp wothout all those steps to save it? On mobile, pardon formatting Link to comment Share on other sites More sharing options...
Deye Posted November 13, 2018 Share Posted November 13, 2018 Hi MaximusCZ, Be on the lookout GDIPlus_BitmapCloneArea for more example look here Deye Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 13, 2018 Author Share Posted November 13, 2018 (edited) Thats where I got the info how to load it as I mentioned in the op, but since there is _saveimage, i was hoping for some _loadimage I missed? Besides, clone needs parameter I am trying to get I have file on disk and its path, how to get the handle? Edited November 13, 2018 by MaximusCZ Link to comment Share on other sites More sharing options...
Deye Posted November 13, 2018 Share Posted November 13, 2018 12 minutes ago, MaximusCZ said: Thats where I got the info how to load it as I mentioned in the op That was a long shot but why not explain with code to better describe the problem so we can also test it .. An So we don't need to long shoot it again Deye Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 13, 2018 Author Share Posted November 13, 2018 What code do you mean? I use $a = _ScreenCapture_Capture ('', x,y,a,b) _ScreenCapture_SaveImage("path\file.bmp",$a) Then I want to have $a, but made not from screen capture, from "path\file.bmp" file instead. Link to comment Share on other sites More sharing options...
Danp2 Posted November 13, 2018 Share Posted November 13, 2018 Have you checked out _GDIPlus_ImageLoadFromFile? Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 13, 2018 Author Share Posted November 13, 2018 Bitmaploadfromfile and imageloadfromfile it returns "0" Link to comment Share on other sites More sharing options...
Aether Posted November 13, 2018 Share Posted November 13, 2018 you need those 2 lines _GDIPlus_BitmapCreateFromFile ( $sFileName ) _GDIPlus_BitmapCreateHBITMAPFromBitmap ( $hBitmap [, $iARGB = 0xFF000000] ) Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 13, 2018 Author Share Posted November 13, 2018 The first line returns handle "0".. Ah... It was missing line _GDIPlus_Startup()....... Thanks all Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 13, 2018 Author Share Posted November 13, 2018 (edited) So no, its still not working as intended. I use code: ;;--Way 1: no matches found _GDIPlus_Startup() ;;--capture and save image $hFind = _ScreenCapture_Capture('', $aPos[0], $aPos[1], $aPos[0] + $aPos[2], $aPos[1] + $aPos[3]) _ScreenCapture_SaveImage ("pathredacted\lol.bmp", $hFind) ;;--load immage $hFind = _GDIPlus_ImageLoadFromFile ("pathredacted\lol.bmp") $hFind = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hFind) ;;--Way 2: No matches found _GDIPlus_Startup() ;;--capture and save image $hFind = _ScreenCapture_Capture('', $aPos[0], $aPos[1], $aPos[0] + $aPos[2], $aPos[1] + $aPos[3]) $hFind = _GDIPlus_BitmapCreateFromHBITMAP($hFind) _GDIPlus_ImageSaveToFile($hFind, "pathredacted\lol.bmp") ;;--load immage $hFind = _GDIPlus_ImageLoadFromFile ("pathredacted\lol.bmp") $hFind = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hFind) ;;--Way 3: Match found, but without saving to disk $hFind = _ScreenCapture_Capture('', $aPos[0], $aPos[1], $aPos[0] + $aPos[2], $aPos[1] + $aPos[3]) ;;--Code after: (using #include "BmpSearch.au3" found here) Local $hSource = _ScreenCapture_Capture('') Local $aCords = _BmpSearch($hSource, $hFind) Its the same if I use either _GDIPlus_BitmapCreateFromFile or _GDIPlus_ImageLoadFromFile If I ommit _GDIPlus_BitmapCreateHBITMAPFromBitmap I get Local $iRowInc = ($tSizeSource.X - $tSizeFind.X) * 4 Local $iRowInc = ($tSizeSource.X - $tSizeFind^ ERROR I get valid handle after loading the bitmap with either method Edited November 13, 2018 by MaximusCZ Link to comment Share on other sites More sharing options...
bolthead Posted November 13, 2018 Share Posted November 13, 2018 You are overwriting the variable $hFind = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hFind) Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 13, 2018 Author Share Posted November 13, 2018 @bolthead intentionally. $hFind is always what is used, from start to finish of this. Link to comment Share on other sites More sharing options...
Aether Posted November 13, 2018 Share Posted November 13, 2018 well your problem resides on this function _bmpsearch ! idk about this, since you haven't expose this function probably comparing apples with oranges ! but hbitmap and bitmap are very different from gdi+ ! Link to comment Share on other sites More sharing options...
MaximusCZ Posted November 14, 2018 Author Share Posted November 14, 2018 (edited) @Aether I hoped there is a way to do completely without gdi+, but then every suggestion here was by using it and I cant find any alternative? The thing is that match is working correctly, IF I dont save the bitmap to disk and only hold it in memory. In the end I want to make bitmap of what to be found, and at runtime checking against this to find it. Here is the bmpsearch.au3 expandcollapse popup#include <WinAPIGdi.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _BmpSearch ; Description ...: Searches for Bitmap in a Bitmap ; Syntax ........: _BmpSearch($hSource, $hFind, $iMax=5000) ; Parameters ....: $hSource - Handle to bitmap to search ; $hFind - Handle to bitmap to find ; $iMax - Max matches to find ; Return values .: Success: Returns a 2d array with the following format: ; $aCords[0][0] = Total Matches found ; $aCords[$i][0] = Width of bitmap ; $aCords[$i][1] = Hight of bitmap ; $aCords[$i][2] = X cordinate ; $aCords[$i][3] = Y cordinate ; ; Failure: Returns 0 and sets @error to 1 ; ; Author ........: Brian J Christy (Beege) ; =============================================================================================================================== Func _BmpSearch($hSource, $hFind, $iMax = 5000) Static Local $aMemBuff, $tMem, $fStartup = True If $fStartup Then ;####### (BinaryStrLen = 490) #### (Base64StrLen = 328 )#################################################################################################### Local $Opcode = 'yBAAAFCNRfyJRfSNRfiJRfBYx0X8AAAAAItVDP8yj0X4i10Ii0UYKdiZuQQAAAD38YnBi0X4OQN0CoPDBOL36akAAACDfSgAdB1TA10oO10YD4OVAAAAi1UkORN1A1vrBluDwwTrvVOLVSyLRTADGjtdGHd3iwg5C3UhA1oEi0gEO10Yd2Y5C3USA1oIi0gIO10Yc1c5' & _ 'C3UDW+sGW4PDBOuCi1UUid6LfQyLTRCJ2AHIO0UYczfzp4P5AHcLSoP6AHQNA3Uc6+KDwwTpVP///4tFIIkYg0UgBIPDBP9F/ItVNDlV/HQG6Tj///9bi0X8ycIwAA==' Local $aDecode = DllCall("Crypt32.dll", "bool", "CryptStringToBinary", "str", $Opcode, "dword", 0, "dword", 1, "struct*", DllStructCreate("byte[254]"), "dword*", 254, "ptr", 0, "ptr", 0) If @error Or (Not $aDecode[0]) Then Return SetError(1, 0, 0) $Opcode = BinaryMid(DllStructGetData($aDecode[4], 1), 1, $aDecode[5]) $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64) $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0]) DllStructSetData($tMem, 1, $Opcode) ;#################################################################################################################################################################################### $fStartup = False EndIf Local $iTime = TimerInit() Local $tSizeSource = _WinAPI_GetBitmapDimension($hSource) Local $tSizeFind = _WinAPI_GetBitmapDimension($hFind) Local $iRowInc = ($tSizeSource.X - $tSizeFind.X) * 4 Local $tSource = _GetBmpPixelStruct($hSource) Local $tFind = _GetBmpPixelStruct($hFind) Local $aFD = _FindFirstDiff($tFind) Local $iFirstDiffIdx = $aFD[0] Local $iFirstDiffPix = $aFD[1] Local $iFirst_Diff_Inc = _FirstDiffInc($iFirstDiffIdx, $tSizeFind.X, $tSizeSource.X) If $iFirst_Diff_Inc < 0 Then $iFirst_Diff_Inc = 0 Local $tCornerPixs = _CornerPixs($tFind, $tSizeFind.X, $tSizeFind.Y) Local $tCornerInc = _CornerInc($tSizeFind.X, $tSizeFind.Y, $tSizeSource.X) Local $pStart = DllStructGetPtr($tSource) Local $iEndAddress = Int($pStart + DllStructGetSize($tSource)) Local $tFound = DllStructCreate('dword[' & $iMax & ']') Local $ret = DllCallAddress('dword', DllStructGetPtr($tMem), 'struct*', $tSource, 'struct*', $tFind, _ 'dword', $tSizeFind.X, 'dword', $tSizeFind.Y, _ 'dword', $iEndAddress, 'dword', $iRowInc, 'struct*', $tFound, _ 'dword', $iFirstDiffPix, 'dword', $iFirst_Diff_Inc, _ 'struct*', $tCornerInc, 'struct*', $tCornerPixs, _ 'dword', $iMax) If Not $ret[0] Then Return SetError(1, 0, 0) Local $aCords = _GetCordsArray($ret[0], $tFound, $tSizeSource.X, $pStart, $tSizeFind.X, $tSizeFind.Y) Return SetExtended(Int(TimerDiff($iTime) * 1000), $aCords) EndFunc ;==>_BmpSearch_MC #Region Internal Functions ;Returns a Dllstructure will all pixels Func _GetBmpPixelStruct($hBMP) Local $tSize = _WinAPI_GetBitmapDimension($hBMP) Local $tBits = DllStructCreate('dword[' & ($tSize.X * $tSize.Y) & ']') _WinAPI_GetBitmapBits($hBMP, DllStructGetSize($tBits), DllStructGetPtr($tBits)) Return $tBits #Tidy_Off #cs This is how the dllstructure index numbers correspond to the pixel cordinates: An 5x5 dimension bmp: X0 X1 X2 X3 X4 Y0 1 2 3 4 5 Y1 6 7 8 9 10 Y2 11 12 13 14 15 Y3 16 17 18 19 20 Y4 21 22 23 24 25 An 8x8 dimension bmp: X0 X1 X2 X3 X4 X5 X6 X7 Y0 1 2 3 4 5 6 7 8 Y1 9 10 11 12 13 14 15 16 Y2 17 18 19 20 21 22 23 24 Y3 25 26 27 28 29 30 31 32 Y4 33 34 35 36 37 38 39 40 Y5 41 42 43 44 45 46 47 48 Y6 49 50 51 52 53 54 55 56 Y7 57 58 59 60 61 62 63 64 #ce #Tidy_On EndFunc ;==>_GetBmpPixelStruct ;Find first pixel that is diffrent than ....the first pixel Func _FindFirstDiff($tPix) ;####### (BinaryStrLen = 106) ######################################################################################################################## Static Local $Opcode = '0xC80000008B5D0C8B1383C3048B4D103913750C83C304E2F7B800000000EB118B5508FF338F028B451029C883C002EB00C9C20C00' Static Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64) Static Local $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0]) Static Local $fSet = DllStructSetData($tMem, 1, $Opcode) ;##################################################################################################################################################### Local $iMaxLoops = (DllStructGetSize($tPix) / 4) - 1 Local $aRet = DllCallAddress('dword', DllStructGetPtr($tMem), 'dword*', 0, 'struct*', $tPix, 'dword', $iMaxLoops) Return $aRet EndFunc ;==>_FindFirstDiff ; Calculates the value to increase pointer by to check first different pixel Func _FirstDiffInc($iDx, $iFind_Xmax, $iSource_Xmax) Local $aFirstDiffCords = _IdxToCords($iDx, $iFind_Xmax) Local $iXDiff = ($iDx - ($aFirstDiffCords[1] * $iFind_Xmax)) - 1 Return (($aFirstDiffCords[1] * $iSource_Xmax) + $iXDiff) * 4 EndFunc ;==>_FirstDiffInc ;Converts the pointer addresses to cordinates Func _GetCordsArray($iTotalFound, $tFound, $iSource_Xmax, $pSource, $iFind_Xmax, $iFind_Ymax) Local $aRet[$iTotalFound + 1][4] $aRet[0][0] = $iTotalFound For $i = 1 To $iTotalFound $iFoundIndex = ((DllStructGetData($tFound, 1, $i) - $pSource) / 4) + 1 $aRet[$i][0] = $iFind_Xmax $aRet[$i][1] = $iFind_Ymax $aRet[$i][3] = Int(($iFoundIndex - 1) / $iSource_Xmax) ; Y $aRet[$i][2] = ($iFoundIndex - 1) - ($aRet[$i][3] * $iSource_Xmax) ; X Next Return $aRet EndFunc ;==>_GetCordsArray ;converts cordinates to dllstructure index number Func _CordsToIdx($iX, $iY, $iMaxX) Return ($iY * $iMaxX) + $iX + 1 EndFunc ;==>_CordsToIdx ;convert dllstructure index number to cordinates Func _IdxToCords($iDx, $iMaxX) Local $aCords[2] $aCords[1] = Int(($iDx - 1) / $iMaxX) ; Y $aCords[0] = ($iDx - 1) - ($aCords[1] * $iMaxX) ; X Return $aCords EndFunc ;==>_IdxToCords ;Retrieves the Pixel Values of Right Top, Left Bottom, Right Bottom. Returns dllstructure Func _CornerPixs(ByRef $tFind, $iFind_Xmax, $iFind_Ymax) Local $tCornerPixs = DllStructCreate('dword[3]') DllStructSetData($tCornerPixs, 1, DllStructGetData($tFind, 1, $iFind_Xmax), 1) ; top right corner DllStructSetData($tCornerPixs, 1, DllStructGetData($tFind, 1, ($iFind_Xmax + ($iFind_Xmax * ($iFind_Ymax - 2)) + 1)), 2) ; bottom left corner DllStructSetData($tCornerPixs, 1, DllStructGetData($tFind, 1, ($iFind_Xmax * $iFind_Ymax)), 3); bottom right corner Return $tCornerPixs EndFunc ;==>_CornerPixs ;Retrieves the pointer adjust values for Right Top, Left Bottom, Right Bottom. Returns dllstructure Func _CornerInc($iFind_Xmax, $iFind_Ymax, $iSource_Xmax) Local $tCornerInc = DllStructCreate('dword[3]') DllStructSetData($tCornerInc, 1, ($iFind_Xmax - 1) * 4, 1) DllStructSetData($tCornerInc, 1, (($iSource_Xmax - $iFind_Xmax) + $iSource_Xmax * ($iFind_Ymax - 2) + 1) * 4, 2) DllStructSetData($tCornerInc, 1, ($iFind_Xmax - 1) * 4, 3) Return $tCornerInc EndFunc ;==>_CornerInc #EndRegion Internal Functions #cs Test/verify Functions Func _TestDiff() Local $hFind = _ScreenCapture_Capture('', 80, 250, 140, 280) Local $hSource = _ScreenCapture_Capture('', 80, 250, 240, 350) Local $tSizeSource = _WinAPI_GetBitmapDimension($hSource) Local $tSizeFind = _WinAPI_GetBitmapDimension($hFind) Local $iSource_Xmax = DllStructGetData($tSizeSource, 'X') Local $iFind_Xmax = DllStructGetData($tSizeFind, 'X') Local $iFind_Ymax = DllStructGetData($tSizeFind, 'Y') Local $tSource = _GetBmpPixelStruct($hSource) Local $tFind = _GetBmpPixelStruct($hFind) Local $aFD = _FindFirstDiff($tFind) Local $iFirstDiffIdx = $aFD[0] Local $iFirstDiffPix = $aFD[1] Local $iFirst_Diff_Inc = _FirstDiffInc($iFirstDiffIdx, $iFind_Xmax, $iSource_Xmax) $p = DllStructGetPtr($tSource) $temp = DllStructCreate('dword', $p + ($iFirst_Diff_Inc)) $sourcepix = Hex(DllStructGetData($temp, 1), 8) _WinAPI_DeleteObject($hSource) _WinAPI_DeleteObject($hFind) EndFunc Func _TestCorners() Local $hFind = _ScreenCapture_Capture('', 1, 1, 100, 100) Local $hSource = _ScreenCapture_Capture('', 1, 1, 250, 350) Local $tSizeSource = _WinAPI_GetBitmapDimension($hSource) Local $tSizeFind = _WinAPI_GetBitmapDimension($hFind) Local $iSource_Xmax = DllStructGetData($tSizeSource, 'X') Local $iFind_Xmax = DllStructGetData($tSizeFind, 'X') Local $iFind_Ymax = DllStructGetData($tSizeFind, 'Y') Local $tSource = _GetBmpPixelStruct($hSource) Local $tFind = _GetBmpPixelStruct($hFind) Local $tCornerPixs = _CornerPixs($tFind, $iFind_Xmax, $iFind_Ymax) Local $tCornerInc = _CornerInc($iFind_Xmax, $iFind_Ymax, $iSource_Xmax) ConsoleWrite('TLC = ' & Hex(DllStructGetData($tFind, 1, 1), 8) & @LF) ConsoleWrite('TRC = ' & Hex(DllStructGetData($tCornerPixs, 1, 1), 8) & @LF) ConsoleWrite('BLC = ' & Hex(DllStructGetData($tCornerPixs, 1, 2), 8) & @LF) ConsoleWrite('BRC = ' & Hex(DllStructGetData($tCornerPixs, 1, 3), 8) & @LF) ConsoleWrite(@LF) $iFirstInc = DllStructGetData($tCornerInc, 1, 1) $iSecond = DllStructGetData($tCornerInc, 1, 2) $iThird = DllStructGetData($tCornerInc, 1, 3) $p = DllStructGetPtr($tSource) $tTLC = DllStructCreate('dword', $p) $tTRC = DllStructCreate('dword', $p + ($iFirstInc)) $tBLC = DllStructCreate('dword', $p + ($iFirstInc+$iSecond)) $tBRC = DllStructCreate('dword', $p + ($iFirstInc+$iSecond+$iThird)) ConsoleWrite('TLC = ' & Hex(DllStructGetData($tTLC, 1), 8) & @LF) ConsoleWrite('TRC = ' & Hex(DllStructGetData($tTRC, 1), 8) & @LF) ConsoleWrite('BLC = ' & Hex(DllStructGetData($tBLC, 1), 8) & @LF) ConsoleWrite('BRC = ' & Hex(DllStructGetData($tBRC, 1), 8) & @LF) _WinAPI_DeleteObject($hSource) _WinAPI_DeleteObject($hFind) EndFunc #ce #cs Assembly Source Func _BmpSearch($hSource, $hFind, $iMax = 5000) Local $iTime = TimerInit() Local $tSizeSource = _WinAPI_GetBitmapDimension($hSource) Local $tSizeFind = _WinAPI_GetBitmapDimension($hFind) Local $iRowInc = ($tSizeSource.X - $tSizeFind.X) * 4 Local $tSource = _GetBmpPixelStruct($hSource) Local $tFind = _GetBmpPixelStruct($hFind) Local $aFD = _FindFirstDiff($tFind) Local $iFirstDiffIdx = $aFD[0] Local $iFirstDiffPix = $aFD[1] Local $iFirst_Diff_Inc = _FirstDiffInc($iFirstDiffIdx, $tSizeFind.X, $tSizeSource.X) If $iFirst_Diff_Inc < 0 Then $iFirst_Diff_Inc = 0 Local $tCornerPixs = _CornerPixs($tFind, $tSizeFind.X, $tSizeFind.Y) Local $tCornerInc = _CornerInc($tSizeFind.X, $tSizeFind.Y, $tSizeSource.X) Local $pStart = DllStructGetPtr($tSource) Local $iEndAddress = Int($pStart + DllStructGetSize($tSource)) _FasmFunc("'struct*', $pSource, 'struct*', $pFind, " & _ "'dword', $iFind_Xmax, 'dword', $iFind_Ymax, " & _ "'dword', $iEndAddress, 'dword', $iRowInc, 'struct*', $pFound, " & _ "'dword', $iFirstDiffPix, 'dword', $iFirst_Diff_Inc, " & _ "'struct*', $pCornerInc, 'struct*', $pCornerPixs, " & _ "'dword', $iMax") _FasmLocalVar('$iTotalFound = 0') ; create var to hold total found matches _FasmAdd("mov edx, $pFind") ; set edx to address of $tFind _FasmLocalVar('$iFirstPixel = dword[edx]'); first pixel to find _FasmAdd("mov ebx, $pSource") ; set ebx to address of $tSource. As we walk through the bitmap, ebx will hold are current postion throughout the whole function. ; Start of main loop _FasmAdd("FindFistPixel:") _FasmAdd(" mov eax, $iEndAddress") ; set eax to $iEndaddress. _FasmAdd(" sub eax, ebx") ; subtract current address - _FasmAdd(' cdq') ; convert dword in eax to qword. the value is placed in edx:eax - (needed for division below) _FasmAdd(' mov ecx, 4') ; ecx = 4 - ecx is the divisor for "div" instruction _FasmAdd(' div ecx') ; eax = (edx:eax)/ecx (fyi - remainder is placed in edx if ever needed) _FasmAdd(' mov ecx, eax'); Set Max Loops -- ecx = ($iEndAddress-$iCurrentAddress) / 4 _FasmAdd(" mov eax, $iFirstPixel") _FasmAdd(" CheckNextPixel:") _FasmJumpIf(' dword[ebx] = eax, CheckFirstDiff') ; Pixels match. Check if first diff pixels match. _FasmAdd(" add ebx, 4") ; increse current address to next pixel _FasmAdd(" loop CheckNextPixel") ; "loop" instruction will decrease ecx each loop and exit when ecx = 0 _FasmAdd("jmp Finished") _FasmAdd("CheckFirstDiff:") _FasmJumpIf(' $iFirst_Diff_Inc = 0, CheckCorners') ; if inc is 0 then 'find' pic is all one color. must skip the diff check. _FasmAdd(" push ebx") ; save current are current address ( position) _FasmAdd(" add ebx, $iFirst_Diff_Inc") ; increase current address to first pixel that is different _FasmJumpIf(" ebx >= $iEndAddress, PopFinished") _FasmAdd(" mov edx, $iFirstDiffPix") ; set edx to pixel value to check _FasmJumpIf(" dword[ebx] <> edx, FirstDiffFail") ; compare pixels. jump to FirstDiffFail if not equal _FasmAdd(" pop ebx") ; restore address _FasmAdd(" jmp CheckCorners") ; _FasmAdd("FirstDiffFail:") _FasmAdd(" pop ebx") ; restore address _FasmAdd(" add ebx, 4") ; increase current address _FasmAdd(" jmp FindFistPixel") ; start over _FasmAdd("CheckCorners:") _FasmAdd(" push ebx") _FasmAdd(" mov edx, $pCornerInc") ; set edx to structure that holds are values to adjust pointer to corners _FasmAdd(" mov eax, $pCornerPixs") ; set ebx to struct that holds pixel values _FasmAdd(" add ebx, dword[edx]") ; increase address to top right corner _FasmJumpIf(" ebx > $iEndAddress, PopFinished") _FasmAdd(" mov ecx, dword[eax]") ; set ecx to pixel value _FasmJumpIf(' dword[ebx] <> ecx, CornerFail') ; compare _FasmAdd(" add ebx, dword[edx+4]") ; increase address to bottom left corner _FasmAdd(" mov ecx, dword[eax+4]") ; set ecx to bottom left pixel value _FasmJumpIf(" ebx > $iEndAddress, PopFinished") _FasmJumpIf(' dword[ebx] <> ecx, CornerFail') ; compare _FasmAdd(" add ebx, dword[edx+8]") ; increase address to bottom right corner _FasmAdd(" mov ecx, dword[eax+8]") ; set pixel value _FasmJumpIf(" ebx >= $iEndAddress, PopFinished") _FasmJumpIf(' dword[ebx] <> ecx, CornerFail') ; compare _FasmAdd(" pop ebx") ; restore orignal address _FasmAdd(" jmp CheckMatch") ; if we are here all corners matched. Now do a full check _FasmAdd("CornerFail:") _FasmAdd(" pop ebx") ; restore address _FasmAdd(" add ebx, 4") ; increase address to next pixel _FasmAdd(" jmp FindFistPixel") ; start over _FasmAdd("CheckMatch:") _FasmAdd(" mov edx, $iFind_Ymax") ; set edx to max number of rows to check _FasmAdd(" mov esi, ebx") ; set esi to current address. esi and edi must be used for the "repe cmpsd" command below _FasmAdd(" mov edi, $pFind") ; set edi to address of find pic _FasmAdd(" NextRow:") _FasmAdd(" mov ecx, $iFind_Xmax") ; set max number of compares _FasmAdd(" mov eax, ebx") ; move current address to ebx _FasmAdd(" add eax, ecx") ; add max compares. _FasmJumpIf(" eax >= $iEndAddress, Finished") ; verify we will not go past end address _FasmAdd(" repe cmpsd") ; repeats comparing bits in edi and esi until bits are not equal or ecx is 0 _FasmJumpIf(" ecx > 0, NextPixel") ; if ecx is > 0 then we found a bits not equal, else the whole row matched _FasmAdd(" dec edx") ; dec row count _FasmJumpIf(" edx = 0, FoundMatch") ; if row count reaches 0 the we have a match. exit loop _FasmAdd(" add esi, $iRowInc") ; increase source address to next row _FasmAdd(" jmp NextRow") ; check next row _FasmAdd("NextPixel:") _FasmAdd(" add ebx, 4"); ; increase address _FasmAdd(" jmp FindFistPixel") ; start over _FasmAdd("FoundMatch:") _FasmAdd(" mov eax, $pFound") ; move pointer of $tFound to eax _FasmAdd(" mov dword[eax], ebx") ; set with address found _FasmAdd(" add $pFound, 4") ; increase address of $pfound. _FasmAdd(" add ebx, 4") ; increase current address _FasmAdd(" inc $iTotalFound") ; increase iTotalfound _FasmAdd(" mov edx, $iMax") ; set edx to max found _FasmJumpIf(' $iTotalFound = edx, Finished') ; verify we are not over are limit. if we are exit _FasmAdd(" jmp FindFistPixel") ; start over ;End main loop _FasmAdd("PopFinished:") _FasmAdd("pop ebx") _FasmAdd("Finished:") _FasmAdd("mov eax, $iTotalFound") _FasmEndFunc() Return _FasmCompileMC('_BmpSearch') Local $pMem = _FasmGetFuncPtr() Local $tFound = DllStructCreate('dword[' & $iMax & ']') Local $ret = DllCallAddress('dword', $pMem, 'struct*', $tSource, 'struct*', $tFind, _ 'dword', $tSizeFind.X, 'dword', $tSizeFind.Y, _ 'dword', $iEndAddress, 'dword', $iRowInc, 'struct*', $tFound, _ 'dword', $iFirstDiffPix, 'dword', $iFirst_Diff_Inc, _ 'struct*', $tCornerInc, 'struct*', $tCornerPixs, _ 'dword', $iMax) If Not $ret[0] Then Return SetError(1, 0, 0) Local $aCords = _GetCordsArray($ret[0], $tFound, $tSizeSource.X, $pStart, $tSizeFind.X, $tSizeFind.Y) Return SetExtended(Int(TimerDiff($iTime) * 1000), $aCords) EndFunc ;==>_BmpSearch Func __FindFirstDiff($tPix) _FasmFunc("'dword*', $iPixFound, 'struct*', $tPix, 'dword', $iMaxLoops") _FasmAdd("mov ebx, $tPix") _FasmAdd("mov edx, dword[ebx]") _FasmAdd("add ebx, 4") _FasmAdd("mov ecx, $iMaxLoops") _FasmAdd("CheckNext:") _FasmJumpIf(' dword[ebx] <> edx, Found') _FasmAdd(" add ebx, 4") _FasmAdd(" loop CheckNext") _FasmAdd("mov eax, 0") _FasmAdd("jmp Finished") _FasmAdd("Found:") _FasmAdd(" mov edx, $iPixFound") _FasmAdd(" push dword[ebx]") _FasmAdd(" pop dword[edx]") _FasmAdd(" mov eax, $iMaxLoops") _FasmAdd(" sub eax, ecx") _FasmAdd(" add eax, 2") _FasmAdd(" jmp Finished") _FasmAdd("Finished:") _FasmEndFunc() _FasmCompileMC('_FindFirstDiff') Local $pMem = _FasmGetFuncPtr() Local $iMaxLoops = (DllStructGetSize($tPix) / 4) - 1 Local $iDx = DllCallAddress('dword', $pMem, 'dword*', 0, 'struct*', $tPix, 'dword', $iMaxLoops) Return $iDx EndFunc ;==>__FindFirstDiff #ce Edited November 14, 2018 by MaximusCZ Link to comment Share on other sites More sharing options...
Aether Posted November 14, 2018 Share Posted November 14, 2018 I was not able to make _BmpSearch work even with this very simple code : #include <ScreenCapture.au3> #include "_BmpSearch.au3" Local $h = WinActivate ("[CLASS:MSPaintApp]") WinWaitActive ($h) $hSource = _ScreenCapture_Capture("", 350,700,450,800) $hFind = _ScreenCapture_Capture('', 380,721,416,758) $res = _BmpSearch($hSource, $hFind) MSGbox (0,"",@error) Always getting an @error ! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now