Phenom Posted June 5, 2010 Share Posted June 5, 2010 (edited) This has a function that finds a BMP within another BMP. Use it like this: $result = _FindBMP($imageToSearch, $imageToFind) $result[1] will hold True if found, false otherwise. If found, then $result[3] will hold the x-coordinate and $result[4] will hold the y-coordinate of the location where the image was found (I think). It doesn't work for me. Can anyone get it to work? This file is based off of http://www.autoitscript.com/forum/index.php?showtopic=66545FindBMP.au3ScreenCaptureFixed.au3 Edited June 5, 2010 by Phenom Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 (edited) The following works for me: (in fact, the originials work for me too) expandcollapse popup;=============================================================================== ; Function Name: findBMP ; Description: Finds a bitmap (.BMP) in another BMP file (other formats BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF should work but not tested) ; Syntax: findBMP($BMP1, $BMP2, $MatchType=TRUE) ; ; Parameter(s): $BMP1 = Filename of bitmap to search in ; $BMP2 = Filename of bitmap to search for ; $MatchType = c24RGBFullMatch, c24RGBPartialMatch, c16RGBFullMatch, c16RGBPartialMatch ; ; Return Value(s): On Success: = Returns Array List ; On Failure: = @error 1 (Control was found but there was an error with the DLLCall) ; ; Author(s): JunkEW ; ; Note(s): ; * Its never an exact match even with TRUE as last few bits are disposed in algorithm and lines below ; are not checked under assumption that those are 99.99% of the time correct ; * locking bits overview http://www.bobpowell.net/lockingbits.htm ; ToDo: ; * Transparency (when search letters on a different background) http://www.winprog.org/tutorial/transparency.html ; * Match quicker by doing a bitblt with srcinvert when first line is found (instead of checking line by line) ; * $BMP1 and $BMP2 to be HBITMAP handle as input instead of filenames (will make searching within partial screen easier) ; Example(s): ; ;=============================================================================== #include "ScreenCaptureFixed.au3" Global Const $c24RGBFullMatch = 1 ;Load as 24 bits and full match Global Const $c24RGBPartialMatch = 2 ;Load as 24 bits and partial match Global Const $c16RGBFullMatch = 3 ;Load as 16 bits and full match Global Const $c16RGBPartialMatch = 4 ;Load as 16 bits and partial match Global $result = _FindBMP("image1.bmp", "image2.bmp") For $I = 0 To $result[0] - 1 ConsoleWrite($result[$I] & @CRLF) Next Func _FindBMP($BMP1, $BMP2, $MatchType = $c24RGBFullMatch) Local $BMP1Data = "", $BMP1Width = 0, $BMP1Height = 0, $BMP1LineWidth = 0; Local $BMP2Data = "", $BMP2Width = 0, $BMP2Height = 0, $BMP2LineWidth = 0 Local $matchedLines = 0, $foundAtLeft = -1, $foundAtTop = -1 ; $foundAt = "", $matchPossible = False, Local $bestMatchLine = -1, $HighestMatchingLines = -1; For knowing when no match is found where best area is Local $iPos = 1; Local $imgBytes; Local $iFuzzyDist, $searchFor, $iAbove, $bMatchPossible, $aboveLine If ($MatchType = $c24RGBFullMatch) Or ($MatchType = $c24RGBPartialMatch) Then $imgBytes = 3 Else $imgBytes = 2 EndIf ; Load the bitmap to search in _GetImage($BMP1, $BMP1Data, $BMP1Width, $BMP1Height, $BMP1LineWidth, $imgBytes) $BMP1Data = BinaryToString($BMP1Data) ; Load the bitmap to find _GetImage($BMP2, $BMP2Data, $BMP2Width, $BMP2Height, $BMP2LineWidth, $imgBytes) ;Make it strings to be able to use string functions for searching $BMP2Data = BinaryToString($BMP2Data) ;For reference of line where in BMP2FindIn a line of BMP2Find was found If $BMP2Height = 0 Then SetError(1, 0, 0) Return False EndIf ;~ Local $fLine[$BMP2Height]; Line number of found line(s), reLocalmed when second picture size is known ;If exact match check every 1 line else do it more fuzzy (as most likely other lines are unique) If ($MatchType = $c24RGBFullMatch) Or ($MatchType = $c16RGBFullMatch) Then $iFuzzyDist = 1 Else ;Check fuzzy every 10% of lines $iFuzzyDist = Ceiling(($BMP2Height * 0.1)) EndIf ;~ Local $begin = TimerInit() ;Look for each line of the bitmap if it exists in the bitmap to find in For $I = 0 To $BMP2Height - 1 ;Minus imgbytes as last bits are padded with unpredictable bytes (24 bits image assumption) or 2 when 16 bits $searchFor = StringMid($BMP2Data, 1 + ($I * $BMP2LineWidth), ($BMP2LineWidth - $imgBytes)) $iPos = StringInStr($BMP1Data, $searchFor, 2, 1, $iPos) ; $iPos = StringInStr($BMP1Data, $searchFor) ;Look for all lines above if there is also a match ;Not doing it for the lines below as speed is more important and risk of mismatch on lines below is small $iAbove = 1 If $iPos > 0 Then $bMatchPossible = True $matchedLines = 1;As first found line is matched we start counting ;Location of the match $foundAtTop = Int($iPos / $BMP1LineWidth) - $I $foundAtLeft = Int(Mod($iPos, $BMP1LineWidth) / $imgBytes) Else $bMatchPossible = False ExitLoop EndIf While (($I + $iAbove) <= ($BMP2Height - 1)) And ($bMatchPossible = True) $searchFor = StringMid($BMP2Data, 1 + (($I + $iAbove) * $BMP2LineWidth), ($BMP2LineWidth - $imgBytes)) $aboveLine = StringMid($BMP1Data, $iPos + ($iAbove * $BMP1LineWidth), ($BMP2LineWidth - $imgBytes)) If $aboveLine <> $searchFor Then $bMatchPossible = False ;To remember the area with the best match If $matchedLines >= $HighestMatchingLines Then $HighestMatchingLines = $matchedLines ;Best guess of location ;~ $foundAtTop = $fline[$i] + $i - $BMP2Height $foundAtTop = Int($iPos / $BMP1LineWidth);+ $i - $BMP2Height $bestMatchLine = Int($iPos / $BMP1LineWidth) EndIf ExitLoop EndIf $matchedLines = $matchedLines + 1 $iAbove = $iAbove + $iFuzzyDist WEnd ;If bMatchPossible is still true most likely we have found the bitmap If $bMatchPossible = True Then ;~ ConsoleWrite("Could match top: " & $foundAtTop & " left: " & $foundAtLeft & " in " & TimerDiff($begin) / 1000 & " seconds" & @LF) ; MouseMove($foundatleft,$foundatTop) ExitLoop Else ;~ consolewrite("i not matched " & $ipos & " " & $matchedlines & @crlf ) EndIf Next ;For some debugging of time ; if $bMatchPossible = True Then ; ConsoleWrite("Searching took " & TimerDiff($begin) / 1000 & " seconds " & @LF) ; Else ; ConsoleWrite("NOT FOUND Searching took " & TimerDiff($begin) / 1000 & " seconds" & @LF) ; endif ;Return an error if not found else return an array with all information If $bMatchPossible = False Then SetError(1, 0, 0) EndIf Return StringSplit($bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $BMP2Width & ";" & $BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine, ";") ;Return $bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $bmp2width & ";" & $BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine EndFunc ;==>_FindBMP Func _GetImage($BMPFile, ByRef $BMPDataStart, ByRef $Width, ByRef $Height, ByRef $Stride, $imgBytes = 3) _GDIPlus_Startup() Local $Scan0, $pixelData, $hbScreen, $pBitmap, $handle ; $pBitmapCap, ; Load the bitmap to search in If $BMPFile = "SCREEN" Then $hbScreen = ScreenCapture_Capture("", 0, 0, -1, -1, False) $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap Else ;try to get a handle $handle = WinGetHandle($BMPFile) If @error Then ;Assume its an unknown handle so correct filename should be given $pBitmap = _GDIPlus_BitmapCreateFromFile($BMPFile) Else $hbScreen = ScreenCapture_CaptureWnd("", $handle, 0, 0, -1, -1, False) $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap EndIf EndIf ;Get $tagGDIPBITMAPDATA structure ;~ ConsoleWrite("Bitmap Width: " & _GDIPlus_ImageGetWidth($pBitmap) & @CRLF ) ;~ ConsoleWrite("Bitmap Height: " & _GDIPlus_ImageGetHeight($pBitmap) & @CRLF) ;~ 24 bits (3 bytes) or 16 bits (2 bytes) comparison If ($imgBytes = 2) Then Local $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF16RGB555) Else $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB) EndIf If @error Then MsgBox(0, "", "Error locking region " & @error) $Stride = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $Width = DllStructGetData($BitmapData, "Width");Image width - Number of pixels in one scan line of the bitmap. $Height = DllStructGetData($BitmapData, "Height");Image height - Number of scan lines in the bitmap. ;~ Local $PixelFormat = DllStructGetData($BitmapData, "PixelFormat");Pixel format - Integer that specifies the pixel format of the bitmap $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap. $pixelData = DllStructCreate("ubyte lData[" & (Abs($Stride) * $Height - 1) & "]", $Scan0) $BMPDataStart = $BMPDataStart & DllStructGetData($pixelData, "lData") _GDIPlus_BitmapUnlockBits($pBitmap, $BitmapData) _GDIPlus_ImageDispose($pBitmap) _GDIPlus_Shutdown() _WinAPI_DeleteObject($pBitmap) _WinAPI_DeleteObject($hbScreen) EndFunc ;==>_GetImage expandcollapse popup#include-once #include <GDIPlus.au3> #include <WinAPI.au3> ; #INDEX# ======================================================================================================================= ; Title .........: Screen Capture ; AutoIt Version: 3.2.3++ ; Language: English ; Description ...: This module allows you to copy the screen or a region of the screen and save it to file. Depending on the type ; of image, you can set various image parameters such as pixel format, quality and compression. ; Author ........: Paul Campbell (PaulIA) ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== Global $giBMPFormat = $GDIP_PXF24RGB Global $giJPGQuality = 100 Global $giTIFColorDepth = 24 Global $giTIFCompression = $GDIP_EVTCOMPRESSIONLZW Global Const $_ScreenCAPTURECONSTANT_SM_CXSCREEN = 0 Global Const $_ScreenCAPTURECONSTANT_SM_CYSCREEN = 1 Global Const $_ScreenCAPTURECONSTANT_SRCCOPY = 0x00CC0020 ; =============================================================================================================================== ;============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;ScreenCapture_Capture ;ScreenCapture_CaptureWnd ;ScreenCapture_SaveImage ;ScreenCapture_SetBMPFormat ;ScreenCapture_SetJPGQuality ;ScreenCapture_SetTIFColorDepth ;ScreenCapture_SetTIFCompression ; =============================================================================================================================== ;============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_Capture ; Description ...: Captures a region of the screen ; Syntax.........: ScreenCapture_Capture([$sFileName = ""[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $iLeft - X coordinate of the upper left corner of the rectangle ; $iTop - Y coordinate of the upper left corner of the rectangle ; $iRight - X coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +width will be used. ; $iBottom - Y coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +height will be used. ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_Capture($sFileName = "", $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $iH, $iW, $hWnd, $hDDC, $hCDC, $hBMP, $aCursor, $aIcon, $hIcon If $iRight = -1 Then $iRight = _WinAPI_GetSystemMetrics($_ScreenCAPTURECONSTANT_SM_CXSCREEN) If $iBottom = -1 Then $iBottom = _WinAPI_GetSystemMetrics($_ScreenCAPTURECONSTANT_SM_CYSCREEN) If $iRight < $iLeft Then Return SetError(-1, 0, 0) If $iBottom < $iTop Then Return SetError(-2, 0, 0) $iW = $iRight - $iLeft $iH = $iBottom - $iTop $hWnd = _WinAPI_GetDesktopWindow() $hDDC = _WinAPI_GetDC($hWnd) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, $_ScreenCAPTURECONSTANT_SRCCOPY) If $fCursor Then $aCursor = _WinAPI_GetCursorInfo() If $aCursor[1] Then $hIcon = _WinAPI_CopyIcon($aCursor[2]) $aIcon = _WinAPI_GetIconInfo($hIcon) _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iLeft, $aCursor[4] - $aIcon[3] - $iTop, $hIcon) _WinAPI_DestroyIcon($hIcon) _WinAPI_DeleteObject($aIcon[4]); <- THIS! _WinAPI_DeleteObject($aIcon[5]); <- THIS! EndIf EndIf _WinAPI_ReleaseDC($hWnd, $hDDC) _WinAPI_DeleteDC($hCDC) If $sFileName = "" Then Return $hBMP ScreenCapture_SaveImage($sFileName, $hBMP) _WinAPI_DeleteObject($hBMP) EndFunc ;==>ScreenCapture_Capture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_CaptureWnd ; Description ...: Captures a screen shot of a specified window ; Syntax.........: ScreenCapture_CaptureWnd($sFileName, $hWnd[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $hWnd - Handle to the window to be captured ; $iLeft - X coordinate of the upper left corner of the client rectangle ; $iTop - Y coordinate of the upper left corner of the client rectangle ; $iRight - X coordinate of the lower right corner of the rectangle ; $iBottom - Y coordinate of the lower right corner of the rectangle ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. All coordinates are in ; client coordinate mode. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; Credits .......: Thanks to SmOke_N for his suggestion for capturing part of the client window ; =============================================================================================================================== Func ScreenCapture_CaptureWnd($sFileName, $hWnd, $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $tRect $tRect = _WinAPI_GetWindowRect($hWnd) $iLeft += DllStructGetData($tRect, "Left") $iTop += DllStructGetData($tRect, "Top") If $iRight = -1 Then $iRight = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left") If $iBottom = -1 Then $iBottom = DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top") $iRight += DllStructGetData($tRect, "Left") $iBottom += DllStructGetData($tRect, "Top") If $iLeft > DllStructGetData($tRect, "Right") Then $iLeft = DllStructGetData($tRect, "Left") If $iTop > DllStructGetData($tRect, "Bottom") Then $iTop = DllStructGetData($tRect, "Top") If $iRight > DllStructGetData($tRect, "Right") Then $iRight = DllStructGetData($tRect, "Right") If $iBottom > DllStructGetData($tRect, "Bottom") Then $iBottom = DllStructGetData($tRect, "Bottom") Return ScreenCapture_Capture($sFileName, $iLeft, $iTop, $iRight, $iBottom, $fCursor) EndFunc ;==>ScreenCapture_CaptureWnd ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SaveImage ; Description ...: Saves an image to file ; Syntax.........: ScreenCapture_SaveImage($sFileName, $hBitmap[, $fFreeBmp = True]) ; Parameters ....: $sFileName - Full path and extension of the bitmap file to be saved ; $hBitmap - HBITMAP handle ; $fFreeBmp - If True, hBitmap will be freed on a successful save ; Return values .: Success - True ; Failure - False ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: This function saves a bitmap to file, converting it to the image format specified by the file name extension. ; For Windows XP, the valid extensions are BMP, GIF, JPEG, PNG and TIF. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: ScreenCapture_Capture ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SaveImage($sFileName, $hBitmap, $fFreeBmp = True) Local $hClone, $sCLSID, $tData, $sExt, $hImage, $pParams, $tParams, $iResult, $iX, $iY _GDIPlus_Startup() If @error Then Return SetError(-1, -1, False) $sExt = StringUpper(__GDIPlus_ExtractFileExt($sFileName)) $sCLSID = _GDIPlus_EncodersGetCLSID($sExt) If $sCLSID = "" Then Return SetError(-2, -2, False) $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) If @error Then Return SetError(-3, -3, False) Switch $sExt Case "BMP" $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) $hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iX, $iY, $giBMPFormat) _GDIPlus_ImageDispose($hImage) $hImage = $hClone Case "JPG", "JPEG" $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $giJPGQuality) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData)) Case "TIF", "TIFF" $tParams = _GDIPlus_ParamInit(2) $tData = DllStructCreate("int ColorDepth;int Compression") DllStructSetData($tData, "ColorDepth", $giTIFColorDepth) DllStructSetData($tData, "Compression", $giTIFCompression) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOLORDEPTH, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "ColorDepth")) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOMPRESSION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Compression")) EndSwitch If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams) $iResult = _GDIPlus_ImageSaveToFileEx($hImage, $sFileName, $sCLSID, $pParams) _GDIPlus_ImageDispose($hImage) If $fFreeBmp Then _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return SetError($iResult = False, 0, $iResult = True) EndFunc ;==>ScreenCapture_SaveImage ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetBMPFormat ; Description ...: Sets the bit format that will be used for BMP screen captures ; Syntax.........: ScreenCapture_SetBMPFormat($iFormat) ; Parameters ....: $iFormat - Image bits per pixel (bpp) setting: ; |0 = 16 bpp; 5 bits for each RGB component ; |1 = 16 bpp; 5 bits for red, 6 bits for green and 5 bits blue ; |2 = 24 bpp; 8 bits for each RGB component ; |3 = 32 bpp; 8 bits for each RGB component. No alpha component. ; |4 = 32 bpp; 8 bits for each RGB and alpha component ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, BMP screen captures default to 24 bpp ; Related .......: ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SetBMPFormat($iFormat) Switch $iFormat Case 0 $giBMPFormat = $GDIP_PXF16RGB555 Case 1 $giBMPFormat = $GDIP_PXF16RGB565 Case 2 $giBMPFormat = $GDIP_PXF24RGB Case 3 $giBMPFormat = $GDIP_PXF32RGB Case 4 $giBMPFormat = $GDIP_PXF32ARGB Case Else $giBMPFormat = $GDIP_PXF24RGB EndSwitch EndFunc ;==>ScreenCapture_SetBMPFormat ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetJPGQuality ; Description ...: Sets the quality level that will be used for JPEG screen captures ; Syntax.........: ScreenCapture_SetJPGQuality($iQuality) ; Parameters ....: $iQuality - The quality level of the image. Must be in the range of 0 to 100. ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, JPEG screen captures default to a quality level of 100 ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetJPGQuality($iQuality) If $iQuality < 0 Then $iQuality = 0 If $iQuality > 100 Then $iQuality = 100 $giJPGQuality = $iQuality EndFunc ;==>ScreenCapture_SetJPGQuality ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFColorDepth ; Description ...: Sets the color depth used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFColorDepth($iDepth) ; Parameters ....: $iDepth - Image color depth: ; | 0 - Default encoder color depth ; |24 - 24 bit ; |32 - 32 bit ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIFF screen captures default to 24 bits ; Related .......: ScreenCapture_SetTIFCompression ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFColorDepth($iDepth) Switch $iDepth Case 24 $giTIFColorDepth = 24 Case 32 $giTIFColorDepth = 32 Case Else $giTIFColorDepth = 0 EndSwitch EndFunc ;==>ScreenCapture_SetTIFColorDepth ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFCompression ; Description ...: Sets the compression used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFCompression($iCompress) ; Parameters ....: $iCompress - Image compression type: ; |0 - Default encoder compression ; |1 - No compression ; |2 - LZW compression ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIF screen captures default to LZW compression ; Related .......: ScreenCapture_SetTIFColorDepth ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFCompression($iCompress) Switch $iCompress Case 1 $giTIFCompression = $GDIP_EVTCOMPRESSIONNONE Case 2 $giTIFCompression = $GDIP_EVTCOMPRESSIONLZW Case Else $giTIFCompression = 0 EndSwitch EndFunc ;==>ScreenCapture_SetTIFCompression Edited June 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Phenom Posted June 5, 2010 Author Share Posted June 5, 2010 When I try to run that I get the following error in FindBMP.au3 (36) : ==> Subscript used with non-Array variable.: For $I = 0 To $result[0] For $I = 0 To $result^ ERROR Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 When I try to run that I get the following error in FindBMP.au3 (36) : ==> Subscript used with non-Array variable.: For $I = 0 To $result[0] For $I = 0 To $result^ ERROR *facepalm* I fixed it. THat's what happens when I don't test every single little thing I do! Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 (edited) Check out this remake that I chunked together using AutoItObject: expandcollapse popup#region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_Fileversion=0.0.0.55 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=p #AutoIt3Wrapper_Res_Language=1033 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d -I "D:\AutoIt\AutoIt Scripts\Includes" #AutoIt3Wrapper_Run_Tidy=y #Tidy_Parameters=/sfc #AutoIt3Wrapper_Run_After=md "%scriptdir%\Versions\%fileversion%" #AutoIt3Wrapper_Run_After=copy "%in%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.au3" #AutoIt3Wrapper_Run_After=copy "%out%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.exe" #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #include "AutoItObject.au3" #include <GDIPlus.au3> #include <WinAPI.au3> #include <Array.au3> _AutoItObject_Startup() Global $BMPinBMP = BMPinBMP() Global $result = $BMPinBMP.FindBMP("image1.bmp", "image2.bmp") ; substitute your own images here If IsArray($result) Then For $i = 0 To UBound($result) - 1 ConsoleWrite($result[$i] & @CRLF) Next EndIf $BMPinBMP = 0 _AutoItObject_Shutdown() #region BMPinBMP Object Func BMPinBMP() Local $this = _AutoItObject_Create(ScreenCapture()) _AutoItObject_AddProperty($this, "c24RGBFullMatch", $ELSCOPE_PRIVATE, 1) ;Load as 24 bits and full match _AutoItObject_AddProperty($this, "c24RGBPartialMatch", $ELSCOPE_PRIVATE, 2) ;Load as 24 bits and partial match _AutoItObject_AddProperty($this, "c16RGBFullMatch", $ELSCOPE_PRIVATE, 3) ;Load as 16 bits and full match _AutoItObject_AddProperty($this, "c16RGBPartialMatch", $ELSCOPE_PRIVATE, 4) ;Load as 16 bits and partial match _AutoItObject_AddProperty($this, "SuccessArr", $ELSCOPE_PRIVATE) _AutoItObject_AddProperty($this, "BMP1Height", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1Width", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1LineWidth", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1Data", $ELSCOPE_PRIVATE, 1) _AutoItObject_AddProperty($this, "BMP2Height", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2Width", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2LineWidth", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2Data", $ELSCOPE_PRIVATE, 2) _AutoItObject_AddDestructor($this, "BMPinBMP_dtor") _AutoItObject_AddMethod($this, "FindBMP", "BMPinBMP_FindBMP") _AutoItObject_AddMethod($this, "GetImage", "BMPinBMP_GetImage", True) _AutoItObject_AddMethod($this, "", "BMPinBMP_") Return $this EndFunc ;==>BMPinBMP Func BMPinBMP_FindBMP($this, $BMP1, $BMP2) Local $MatchType = $this.c24RGBFullMatch Local $matchedLines = 0, $foundAtLeft = -1, $foundAtTop = -1 ; $foundAt = "", $matchPossible = False, Local $bestMatchLine = -1, $HighestMatchingLines = -1; For knowing when no match is found where best area is Local $iPos = 1, $iFuzzyDist, $searchFor, $iAbove, $bMatchPossible, $aboveLine If ($MatchType = $this.c24RGBFullMatch) Or ($MatchType = $this.c24RGBPartialMatch) Then Local $imgBytes = 3 Else $imgBytes = 2 EndIf ; Load the bitmap to search in $this.GetImage($BMP1, 1, $imgBytes) $this.BMP1Data = BinaryToString($this.BMP1Data) ; Load the bitmap to find $this.GetImage($BMP2, 2, $imgBytes) ;Make it a string to be able to use string functions for searching $this.BMP2Data = BinaryToString($this.BMP2Data) ;For reference of line where in BMP2FindIn a line of BMP2Find was found If $this.BMP2Height = 0 Then Return SetError(1, 0, 0) ;~ Local $fLine[$BMP2Height]; Line number of found line(s), reLocalmed when second picture size is known ;If exact match check every 1 line else do it more fuzzy (as most likely other lines are unique) If ($MatchType = $this.c24RGBFullMatch) Or ($MatchType = $this.c16RGBFullMatch) Then $iFuzzyDist = 1 Else ;Check fuzzy every 10% of lines $iFuzzyDist = Ceiling(($this.BMP2Height * 0.1)) EndIf ;~ Local $begin = TimerInit() For $i = 0 To $this.BMP2Height - 1 ;Look for each line of the bitmap if it exists in the bitmap to find in ;Minus imgbytes as last bits are padded with unpredictable bytes (24 bits image assumption) or 2 when 16 bits $searchFor = StringMid($this.BMP2Data, 1 + ($i * $this.BMP2LineWidth), ($this.BMP2LineWidth - $imgBytes)) $iPos = StringInStr($this.BMP1Data, $searchFor, 2, 1, $iPos) ;$iPos = StringInStr($this.BMP1Data, $searchFor) ;Look for all lines above if there is also a match ;Not doing it for the lines below as speed is more important and risk of mismatch on lines below is small $iAbove = 1 If $iPos > 0 Then $bMatchPossible = True $matchedLines = 1;As first found line is matched we start counting ;Location of the match $foundAtTop = Int($iPos / $this.BMP1LineWidth) - $i $foundAtLeft = Int(Mod($iPos, $this.BMP1LineWidth) / $imgBytes) Else $bMatchPossible = False ExitLoop EndIf While (($i + $iAbove) <= ($this.BMP2Height - 1)) And ($bMatchPossible = True) $searchFor = StringMid($this.BMP2Data, 1 + (($i + $iAbove) * $this.BMP2LineWidth), ($this.BMP2LineWidth - $imgBytes)) $aboveLine = StringMid($this.BMP1Data, $iPos + ($iAbove * $this.BMP1LineWidth), ($this.BMP2LineWidth - $imgBytes)) If $aboveLine <> $searchFor Then $bMatchPossible = False ;To remember the area with the best match If $matchedLines >= $HighestMatchingLines Then $HighestMatchingLines = $matchedLines ;Best guess of location ;~ $foundAtTop = $fline[$i] + $i - $this.BMP2Height $foundAtTop = Int($iPos / $this.BMP1LineWidth);+ $i - $this.BMP2Height $bestMatchLine = Int($iPos / $this.BMP1LineWidth) EndIf ExitLoop EndIf $matchedLines += 1 $iAbove += $iFuzzyDist WEnd ;If bMatchPossible is still true most likely we have found the bitmap If $bMatchPossible = True Then ;~ ConsoleWrite("Could match top: " & $foundAtTop & " left: " & $foundAtLeft & " in " & TimerDiff($begin) / 1000 & " seconds" & @LF) ;MouseMove($foundatleft,$foundatTop) ExitLoop ;~ Else ;~ consolewrite("i not matched " & $ipos & " " & $matchedlines & @crlf ) EndIf Next ;For some debugging of time ; if $bMatchPossible = True Then ; ConsoleWrite("Searching took " & TimerDiff($begin) / 1000 & " seconds " & @LF) ; Else ; ConsoleWrite("NOT FOUND Searching took " & TimerDiff($begin) / 1000 & " seconds" & @LF) ; endif ;Return an error if not found else return an array with all information If $bMatchPossible = False Then SetError(1, 0, 0) $this.SuccessArr = StringSplit($bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $this.BMP2Width & ";" & $this.BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine, ";", 2) ;Return $bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $this.bmp2width & ";" & $this.BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine Return $this.SuccessArr EndFunc ;==>BMPinBMP_FindBMP Func BMPinBMP_GetImage($this, $BMPFile, $image, $imgBytes = 3) _GDIPlus_Startup() If $BMPFile == "SCREEN" Then ; Load the bitmap to search in Local $hbScreen = $this.Capture("", 0, 0, -1, -1, False) Local $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap Else ;try to get a handle Local $handle = WinGetHandle($BMPFile) If @error Then ;Assume its an unknown handle so correct filename should be given $pBitmap = _GDIPlus_BitmapCreateFromFile($BMPFile) Else $hbScreen = $this.CaptureWnd("", $handle, 0, 0, -1, -1, False) $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap EndIf EndIf ;Get $tagGDIPBITMAPDATA structure ;~ ConsoleWrite("Bitmap Width: " & _GDIPlus_ImageGetWidth($pBitmap) & @CRLF ) ;~ ConsoleWrite("Bitmap Height: " & _GDIPlus_ImageGetHeight($pBitmap) & @CRLF) ;~ 24 bits (3 bytes) or 16 bits (2 bytes) comparison If ($imgBytes = 2) Then Local $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF16RGB555) Else $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB) EndIf If @error Then MsgBox(0, "", "Error locking region " & @error) If $image = 1 Then $this.BMP1LineWidth = DllStructGetData($BitmapData, "Stride") ;Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $this.BMP1Width = DllStructGetData($BitmapData, "Width") ;Image width - Number of pixels in one scan line of the bitmap. $this.BMP1Height = DllStructGetData($BitmapData, "Height") ;Image height - Number of scan lines in the bitmap. ;~ Local $PixelFormat = DllStructGetData($BitmapData, "PixelFormat") ;Pixel format - Integer that specifies the pixel format of the bitmap Local $Scan0 = DllStructGetData($BitmapData, "Scan0") ;Scan0 - Pointer to the first (index 0) scan line of the bitmap. Local $pixelData = DllStructCreate("ubyte lData[" & (Abs($this.BMP1LineWidth) * $this.BMP1Height - 1) & "]", $Scan0) $this.BMP1Data = DllStructGetData($pixelData, "lData") ElseIf $image = 2 Then $this.BMP2LineWidth = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $this.BMP2Width = DllStructGetData($BitmapData, "Width");Image width - Number of pixels in one scan line of the bitmap. $this.BMP2Height = DllStructGetData($BitmapData, "Height");Image height - Number of scan lines in the bitmap. ;~ $PixelFormat = DllStructGetData($BitmapData, "PixelFormat");Pixel format - Integer that specifies the pixel format of the bitmap $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap. $pixelData = DllStructCreate("ubyte lData[" & (Abs($this.BMP2LineWidth) * $this.BMP2Height - 1) & "]", $Scan0) $this.BMP2Data = DllStructGetData($pixelData, "lData") EndIf _GDIPlus_BitmapUnlockBits($pBitmap, $BitmapData) _GDIPlus_ImageDispose($pBitmap) _GDIPlus_Shutdown() ;~ _WinAPI_DeleteObject($pBitmap) ;~ _WinAPI_DeleteObject($hbScreen) Return $this EndFunc ;==>BMPinBMP_GetImage #endregion BMPinBMP Object #region ScreenCapture Object ; #INDEX# ======================================================================================================================= ; Title .........: Screen Capture ; AutoIt Version: 3.2.3++ ; Language: English ; Description ...: This module allows you to copy the screen or a region of the screen and save it to file. Depending on the type ; of image, you can set various image parameters such as pixel format, quality and compression. ; Author ........: Paul Campbell (PaulIA) ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;ScreenCapture_Capture ;ScreenCapture_CaptureWnd ;ScreenCapture_SaveImage ;ScreenCapture_SetBMPFormat ;ScreenCapture_SetJPGQuality ;ScreenCapture_SetTIFColorDepth ;ScreenCapture_SetTIFCompression ; =============================================================================================================================== Func ScreenCapture() Local $this = _AutoItObject_Create() _AutoItObject_AddProperty($this, "giBMPFormat", $ELSCOPE_PRIVATE, $GDIP_PXF24RGB) _AutoItObject_AddProperty($this, "giJPGQuality", $ELSCOPE_PRIVATE, 100) _AutoItObject_AddProperty($this, "giTIFColorDepth", $ELSCOPE_PRIVATE, 24) _AutoItObject_AddProperty($this, "giTIFCompression", $ELSCOPE_PRIVATE, $GDIP_EVTCOMPRESSIONLZW) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SM_CXSCREEN", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SM_CYSCREEN", $ELSCOPE_PRIVATE, 1) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SRCCOPY", $ELSCOPE_PRIVATE, 0x00CC0020) _AutoItObject_AddMethod($this, "Capture", "ScreenCapture_Capture", True) _AutoItObject_AddMethod($this, "CaptureWnd", "ScreenCapture_CaptureWnd", True) _AutoItObject_AddMethod($this, "SaveImage", "ScreenCapture_SaveImage", True) _AutoItObject_AddMethod($this, "SetBMPFormat", "ScreenCapture_SetBMPFormat", True) _AutoItObject_AddMethod($this, "SetJPGQuality", "ScreenCapture_SetJPGQuality", True) _AutoItObject_AddMethod($this, "SetTIFColorDepth", "ScreenCapture_SetTIFColorDepth", True) _AutoItObject_AddMethod($this, "SetTIFCompression", "ScreenCapture_SetTIFCompression", True) Return $this EndFunc ;==>ScreenCapture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_Capture ; Description ...: Captures a region of the screen ; Syntax.........: ScreenCapture_Capture([$sFileName = ""[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $iLeft - X coordinate of the upper left corner of the rectangle ; $iTop - Y coordinate of the upper left corner of the rectangle ; $iRight - X coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +width will be used. ; $iBottom - Y coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +height will be used. ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_Capture($this, $sFileName = "", $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $iH, $iW, $hWnd, $hDDC, $hCDC, $hBMP, $aCursor, $aIcon, $hIcon If $iRight = -1 Then $iRight = _WinAPI_GetSystemMetrics($this.ScreenCAPTURECONSTANT_SM_CXSCREEN) If $iBottom = -1 Then $iBottom = _WinAPI_GetSystemMetrics($this.ScreenCAPTURECONSTANT_SM_CYSCREEN) If $iRight < $iLeft Then Return SetError(-1, 0, 0) If $iBottom < $iTop Then Return SetError(-2, 0, 0) $iW = $iRight - $iLeft $iH = $iBottom - $iTop $hWnd = _WinAPI_GetDesktopWindow() $hDDC = _WinAPI_GetDC($hWnd) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, $this.ScreenCAPTURECONSTANT_SRCCOPY) If $fCursor Then $aCursor = _WinAPI_GetCursorInfo() If $aCursor[1] Then $hIcon = _WinAPI_CopyIcon($aCursor[2]) $aIcon = _WinAPI_GetIconInfo($hIcon) _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iLeft, $aCursor[4] - $aIcon[3] - $iTop, $hIcon) _WinAPI_DestroyIcon($hIcon) _WinAPI_DeleteObject($aIcon[4]); <- THIS! _WinAPI_DeleteObject($aIcon[5]); <- THIS! EndIf EndIf _WinAPI_ReleaseDC($hWnd, $hDDC) _WinAPI_DeleteDC($hCDC) If $sFileName = "" Then Return $hBMP $this.SaveImage($sFileName, $hBMP) _WinAPI_DeleteObject($hBMP) EndFunc ;==>ScreenCapture_Capture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_CaptureWnd ; Description ...: Captures a screen shot of a specified window ; Syntax.........: ScreenCapture_CaptureWnd($sFileName, $hWnd[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $hWnd - Handle to the window to be captured ; $iLeft - X coordinate of the upper left corner of the client rectangle ; $iTop - Y coordinate of the upper left corner of the client rectangle ; $iRight - X coordinate of the lower right corner of the rectangle ; $iBottom - Y coordinate of the lower right corner of the rectangle ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. All coordinates are in ; client coordinate mode. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; Credits .......: Thanks to SmOke_N for his suggestion for capturing part of the client window ; =============================================================================================================================== Func ScreenCapture_CaptureWnd($sFileName, $hWnd, $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $tRect $tRect = _WinAPI_GetWindowRect($hWnd) $iLeft += DllStructGetData($tRect, "Left") $iTop += DllStructGetData($tRect, "Top") If $iRight = -1 Then $iRight = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left") If $iBottom = -1 Then $iBottom = DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top") $iRight += DllStructGetData($tRect, "Left") $iBottom += DllStructGetData($tRect, "Top") If $iLeft > DllStructGetData($tRect, "Right") Then $iLeft = DllStructGetData($tRect, "Left") If $iTop > DllStructGetData($tRect, "Bottom") Then $iTop = DllStructGetData($tRect, "Top") If $iRight > DllStructGetData($tRect, "Right") Then $iRight = DllStructGetData($tRect, "Right") If $iBottom > DllStructGetData($tRect, "Bottom") Then $iBottom = DllStructGetData($tRect, "Bottom") Return ScreenCapture_Capture($sFileName, $iLeft, $iTop, $iRight, $iBottom, $fCursor) EndFunc ;==>ScreenCapture_CaptureWnd ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SaveImage ; Description ...: Saves an image to file ; Syntax.........: ScreenCapture_SaveImage($sFileName, $hBitmap[, $fFreeBmp = True]) ; Parameters ....: $sFileName - Full path and extension of the bitmap file to be saved ; $hBitmap - HBITMAP handle ; $fFreeBmp - If True, hBitmap will be freed on a successful save ; Return values .: Success - True ; Failure - False ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: This function saves a bitmap to file, converting it to the image format specified by the file name extension. ; For Windows XP, the valid extensions are BMP, GIF, JPEG, PNG and TIF. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: ScreenCapture_Capture ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SaveImage($this, $sFileName, $hBitmap, $fFreeBmp = True) Local $hClone, $sCLSID, $tData, $sExt, $hImage, $pParams, $tParams, $iResult, $iX, $iY _GDIPlus_Startup() If @error Then Return SetError(-1, -1, False) $sExt = StringUpper(__GDIPlus_ExtractFileExt($sFileName)) $sCLSID = _GDIPlus_EncodersGetCLSID($sExt) If $sCLSID = "" Then Return SetError(-2, -2, False) $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) If @error Then Return SetError(-3, -3, False) Switch $sExt Case "BMP" $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) $hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iX, $iY, $this.giBMPFormat) _GDIPlus_ImageDispose($hImage) $hImage = $hClone Case "JPG", "JPEG" $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $this.giJPGQuality) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData)) Case "TIF", "TIFF" $tParams = _GDIPlus_ParamInit(2) $tData = DllStructCreate("int ColorDepth;int Compression") DllStructSetData($tData, "ColorDepth", $this.giTIFColorDepth) DllStructSetData($tData, "Compression", $this.giTIFCompression) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOLORDEPTH, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "ColorDepth")) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOMPRESSION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Compression")) EndSwitch If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams) $iResult = _GDIPlus_ImageSaveToFileEx($hImage, $sFileName, $sCLSID, $pParams) _GDIPlus_ImageDispose($hImage) If $fFreeBmp Then _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return SetError($iResult = False, 0, $iResult = True) EndFunc ;==>ScreenCapture_SaveImage ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetBMPFormat ; Description ...: Sets the bit format that will be used for BMP screen captures ; Syntax.........: ScreenCapture_SetBMPFormat($iFormat) ; Parameters ....: $iFormat - Image bits per pixel (bpp) setting: ; |0 = 16 bpp; 5 bits for each RGB component ; |1 = 16 bpp; 5 bits for red, 6 bits for green and 5 bits blue ; |2 = 24 bpp; 8 bits for each RGB component ; |3 = 32 bpp; 8 bits for each RGB component. No alpha component. ; |4 = 32 bpp; 8 bits for each RGB and alpha component ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, BMP screen captures default to 24 bpp ; Related .......: ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SetBMPFormat($this, $iFormat) Switch $iFormat Case 0 $this.giBMPFormat = $GDIP_PXF16RGB555 Case 1 $this.giBMPFormat = $GDIP_PXF16RGB565 Case 2 $this.giBMPFormat = $GDIP_PXF24RGB Case 3 $this.giBMPFormat = $GDIP_PXF32RGB Case 4 $this.giBMPFormat = $GDIP_PXF32ARGB Case Else $this.giBMPFormat = $GDIP_PXF24RGB EndSwitch Return $this EndFunc ;==>ScreenCapture_SetBMPFormat ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetJPGQuality ; Description ...: Sets the quality level that will be used for JPEG screen captures ; Syntax.........: ScreenCapture_SetJPGQuality($iQuality) ; Parameters ....: $iQuality - The quality level of the image. Must be in the range of 0 to 100. ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, JPEG screen captures default to a quality level of 100 ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetJPGQuality($this, $iQuality) If $iQuality < 0 Then $iQuality = 0 If $iQuality > 100 Then $iQuality = 100 $this.giJPGQuality = $iQuality Return $this EndFunc ;==>ScreenCapture_SetJPGQuality ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFColorDepth ; Description ...: Sets the color depth used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFColorDepth($iDepth) ; Parameters ....: $iDepth - Image color depth: ; | 0 - Default encoder color depth ; |24 - 24 bit ; |32 - 32 bit ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIFF screen captures default to 24 bits ; Related .......: ScreenCapture_SetTIFCompression ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFColorDepth($this, $iDepth) Switch $iDepth Case 24 $this.giTIFColorDepth = 24 Case 32 $this.giTIFColorDepth = 32 Case Else $this.giTIFColorDepth = 0 EndSwitch Return $this EndFunc ;==>ScreenCapture_SetTIFColorDepth ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFCompression ; Description ...: Sets the compression used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFCompression($iCompress) ; Parameters ....: $iCompress - Image compression type: ; |0 - Default encoder compression ; |1 - No compression ; |2 - LZW compression ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIF screen captures default to LZW compression ; Related .......: ScreenCapture_SetTIFColorDepth ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFCompression($this, $iCompress) Switch $iCompress Case 1 $this.giTIFCompression = $GDIP_EVTCOMPRESSIONNONE Case 2 $this.giTIFCompression = $GDIP_EVTCOMPRESSIONLZW Case Else $this.giTIFCompression = 0 EndSwitch Return $this EndFunc ;==>ScreenCapture_SetTIFCompression #endregion ScreenCapture Object Edited June 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Phenom Posted June 5, 2010 Author Share Posted June 5, 2010 Is this supposed to go all in one file? Because when I include this file, I get the error (14,10) : ERROR: can't open include file "AutoItObject.au3" Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 (edited) Is this supposed to go all in one file? Because when I include this file, I get the error(14,10) : ERROR: can't open include file "AutoItObject.au3"Yes, all into one file.Btw, I think I may have found an error. In the GetImage() function there is this line: Local $handle = WinGetHandle($BMPFile). Well, $BMPFile isn't a window. No, nevermind, it's fine.The only major bug that I see now is that it reports false even though a match was found.For some reason, whenever a match is found within the two bitmaps then the For loop within the FindBMP function will loop for a second time. This seems to me to be unusual behavior. Edited June 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 (edited) Ok, I feel confident that I have pretty well debugged this. expandcollapse popup#region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_Fileversion=0.0.0.55 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=p #AutoIt3Wrapper_Res_Language=1033 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #AutoIt3Wrapper_AU3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d -I "D:\AutoIt\AutoIt Scripts\Includes" #AutoIt3Wrapper_Run_Tidy=y #Tidy_Parameters=/sfc #AutoIt3Wrapper_Run_After=md "%scriptdir%\Versions\%fileversion%" #AutoIt3Wrapper_Run_After=copy "%in%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.au3" #AutoIt3Wrapper_Run_After=copy "%out%" "%scriptdir%\Versions\%fileversion%\%scriptfile%%fileversion%.exe" #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #include "AutoItObject.au3" #include <GDIPlus.au3> #include <WinAPI.au3> #include <Array.au3> _AutoItObject_Startup() Global $BMPinBMP = BMPinBMP() Global $result = $BMPinBMP.FindBMP("image1.bmp", "image2.bmp", 1) ; substitute your own images here If IsArray($result) Then Global $resultArr[8] = ["Possible Match ", "Matched Lines ", "Found at left ", "Found at top ", "2nd BMP Width ", "2nd BMP Height ", "Highest Matching Lines ", "Best match line "] For $i = 0 To UBound($result) - 1 ConsoleWrite($resultArr[$i] & $result[$i] & @CRLF) Next EndIf $BMPinBMP = 0 _AutoItObject_Shutdown() #region BMPinBMP Object Func BMPinBMP() Local $this = _AutoItObject_Create(ScreenCapture()) _AutoItObject_AddProperty($this, "c24RGBFullMatch", $ELSCOPE_PRIVATE, 1) ;Load as 24 bits and full match _AutoItObject_AddProperty($this, "c24RGBPartialMatch", $ELSCOPE_PRIVATE, 2) ;Load as 24 bits and partial match _AutoItObject_AddProperty($this, "c16RGBFullMatch", $ELSCOPE_PRIVATE, 3) ;Load as 16 bits and full match _AutoItObject_AddProperty($this, "c16RGBPartialMatch", $ELSCOPE_PRIVATE, 4) ;Load as 16 bits and partial match _AutoItObject_AddProperty($this, "SuccessArr", $ELSCOPE_PRIVATE) _AutoItObject_AddProperty($this, "BMP1Height", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1Width", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1LineWidth", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1Data", $ELSCOPE_PRIVATE, 1) _AutoItObject_AddProperty($this, "BMP2Height", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2Width", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2LineWidth", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2Data", $ELSCOPE_PRIVATE, 2) _AutoItObject_AddMethod($this, "FindBMP", "BMPinBMP_FindBMP") _AutoItObject_AddMethod($this, "GetImage", "BMPinBMP_GetImage", True) Return $this EndFunc ;==>BMPinBMP Func BMPinBMP_FindBMP($this, $BMP1, $BMP2, $MatchType = 1) Local $matchedLines = 0, $foundAtLeft = -1, $foundAtTop = -1 ; $foundAt = "", $matchPossible = False, Local $bestMatchLine = -1, $HighestMatchingLines = -1; For knowing when no match is found where best area is Local $iPos = 1, $iFuzzyDist, $searchFor, $iAbove, $aboveLine If ($MatchType = $this.c24RGBFullMatch) Or ($MatchType = $this.c24RGBPartialMatch) Then Local $imgBytes = 3 Else $imgBytes = 2 EndIf ; Load the bitmap to search in $this.GetImage($BMP1, 1, $imgBytes) $this.BMP1Data = BinaryToString($this.BMP1Data) ; Load the bitmap to find $this.GetImage($BMP2, 2, $imgBytes) ;Make it a string to be able to use string functions for searching $this.BMP2Data = BinaryToString($this.BMP2Data) ;For reference of line where in BMP2FindIn a line of BMP2Find was found If $this.BMP2Height = 0 Then Return SetError(1) ;~ Local $fLine[$BMP2Height]; Line number of found line(s), reLocalmed when second picture size is known ;If exact match check every 1 line else do it more fuzzy (as most likely other lines are unique) If ($MatchType = $this.c24RGBFullMatch) Or ($MatchType = $this.c16RGBFullMatch) Then $iFuzzyDist = 1 Else ;Check fuzzy every 10% of lines $iFuzzyDist = Ceiling(($this.BMP2Height * 0.1)) EndIf Local $bMatchPossible For $i = 0 To $this.BMP2Height - 1 ;Look for each line of the bitmap if it exists in the bitmap to find in ;Minus imgbytes as last bits are padded with unpredictable bytes (24 bits image assumption) or 2 when 16 bits $searchFor = StringMid($this.BMP2Data, 1 + ($i * $this.BMP2LineWidth), ($this.BMP2LineWidth - $imgBytes)) $iPos = StringInStr($this.BMP1Data, $searchFor, 2, 1, $iPos) ;$iPos = StringInStr($this.BMP1Data, $searchFor) ;Look for all lines above if there is also a match ;Not doing it for the lines below as speed is more important and risk of mismatch on lines below is small $iAbove = 1 If $iPos > 0 Then $bMatchPossible = True $matchedLines = 1 ;As first found line is matched we start counting ;Location of the match $foundAtTop = Int($iPos / $this.BMP1LineWidth) - $i $foundAtLeft = Int(Mod($iPos, $this.BMP1LineWidth) / $imgBytes) While $i + $iAbove <= $this.BMP2Height - 1 $searchFor = StringMid($this.BMP2Data, 1 + (($i + $iAbove) * $this.BMP2LineWidth), $this.BMP2LineWidth - $imgBytes) $aboveLine = StringMid($this.BMP1Data, $iPos + ($iAbove * $this.BMP1LineWidth), $this.BMP2LineWidth - $imgBytes) If $aboveLine <> $searchFor Then ;To remember the area with the best match If $matchedLines >= $HighestMatchingLines Then $HighestMatchingLines = $matchedLines ;Best guess of location ;~ $foundAtTop = $fline[$i] + $i - $this.BMP2Height $foundAtTop = Int($iPos / $this.BMP1LineWidth);+ $i - $this.BMP2Height $bestMatchLine = Int($iPos / $this.BMP1LineWidth) EndIf ExitLoop EndIf $matchedLines += 1 $iAbove += $iFuzzyDist WEnd ElseIf $iPos = 0 Then Return SetError(2) EndIf If $bMatchPossible = True Then ExitLoop ;If bMatchPossible is still true most likely we have found the bitmap Next Return StringSplit($bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $this.BMP2Width & ";" & $this.BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine, ";", 2) EndFunc ;==>BMPinBMP_FindBMP Func BMPinBMP_GetImage($this, $BMPFile, $image, $imgBytes = 3) _GDIPlus_Startup() If $BMPFile == "SCREEN" Then ; Load the bitmap to search in Local $hbScreen = $this.Capture("", 0, 0, -1, -1, False) Local $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap Else ;try to get a handle Local $handle = WinGetHandle($BMPFile) If @error Then ;Assume its an unknown handle so correct filename should be given $pBitmap = _GDIPlus_BitmapCreateFromFile($BMPFile) Else $hbScreen = $this.CaptureWnd("", $handle, 0, 0, -1, -1, False) $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap EndIf EndIf ;Get $tagGDIPBITMAPDATA structure ;~ ConsoleWrite("Bitmap Width: " & _GDIPlus_ImageGetWidth($pBitmap) & @CRLF ) ;~ ConsoleWrite("Bitmap Height: " & _GDIPlus_ImageGetHeight($pBitmap) & @CRLF) ;~ 24 bits (3 bytes) or 16 bits (2 bytes) comparison If ($imgBytes = 2) Then Local $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF16RGB555) Else $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB) EndIf If @error Then MsgBox(0, "", "Error locking region " & @error) If $image = 1 Then $this.BMP1LineWidth = DllStructGetData($BitmapData, "Stride") ;Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $this.BMP1Width = DllStructGetData($BitmapData, "Width") ;Image width - Number of pixels in one scan line of the bitmap. $this.BMP1Height = DllStructGetData($BitmapData, "Height") ;Image height - Number of scan lines in the bitmap. ;~ Local $PixelFormat = DllStructGetData($BitmapData, "PixelFormat") ;Pixel format - Integer that specifies the pixel format of the bitmap Local $Scan0 = DllStructGetData($BitmapData, "Scan0") ;Scan0 - Pointer to the first (index 0) scan line of the bitmap. Local $pixelData = DllStructCreate("ubyte lData[" & (Abs($this.BMP1LineWidth) * $this.BMP1Height - 1) & "]", $Scan0) $this.BMP1Data = DllStructGetData($pixelData, "lData") ElseIf $image = 2 Then $this.BMP2LineWidth = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $this.BMP2Width = DllStructGetData($BitmapData, "Width");Image width - Number of pixels in one scan line of the bitmap. $this.BMP2Height = DllStructGetData($BitmapData, "Height");Image height - Number of scan lines in the bitmap. ;~ $PixelFormat = DllStructGetData($BitmapData, "PixelFormat");Pixel format - Integer that specifies the pixel format of the bitmap $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap. $pixelData = DllStructCreate("ubyte lData[" & (Abs($this.BMP2LineWidth) * $this.BMP2Height - 1) & "]", $Scan0) $this.BMP2Data = DllStructGetData($pixelData, "lData") EndIf _GDIPlus_BitmapUnlockBits($pBitmap, $BitmapData) _GDIPlus_ImageDispose($pBitmap) _GDIPlus_Shutdown() ;~ _WinAPI_DeleteObject($pBitmap) ;~ _WinAPI_DeleteObject($hbScreen) Return $this EndFunc ;==>BMPinBMP_GetImage #endregion BMPinBMP Object #region ScreenCapture Object ; #INDEX# ======================================================================================================================= ; Title .........: Screen Capture ; AutoIt Version: 3.2.3++ ; Language: English ; Description ...: This module allows you to copy the screen or a region of the screen and save it to file. Depending on the type ; of image, you can set various image parameters such as pixel format, quality and compression. ; Author ........: Paul Campbell (PaulIA) ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;ScreenCapture_Capture ;ScreenCapture_CaptureWnd ;ScreenCapture_SaveImage ;ScreenCapture_SetBMPFormat ;ScreenCapture_SetJPGQuality ;ScreenCapture_SetTIFColorDepth ;ScreenCapture_SetTIFCompression ; =============================================================================================================================== Func ScreenCapture() Local $this = _AutoItObject_Create() _AutoItObject_AddProperty($this, "giBMPFormat", $ELSCOPE_PRIVATE, $GDIP_PXF24RGB) _AutoItObject_AddProperty($this, "giJPGQuality", $ELSCOPE_PRIVATE, 100) _AutoItObject_AddProperty($this, "giTIFColorDepth", $ELSCOPE_PRIVATE, 24) _AutoItObject_AddProperty($this, "giTIFCompression", $ELSCOPE_PRIVATE, $GDIP_EVTCOMPRESSIONLZW) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SM_CXSCREEN", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SM_CYSCREEN", $ELSCOPE_PRIVATE, 1) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SRCCOPY", $ELSCOPE_PRIVATE, 0x00CC0020) _AutoItObject_AddMethod($this, "Capture", "ScreenCapture_Capture", True) _AutoItObject_AddMethod($this, "CaptureWnd", "ScreenCapture_CaptureWnd", True) _AutoItObject_AddMethod($this, "SaveImage", "ScreenCapture_SaveImage", True) _AutoItObject_AddMethod($this, "SetBMPFormat", "ScreenCapture_SetBMPFormat", True) _AutoItObject_AddMethod($this, "SetJPGQuality", "ScreenCapture_SetJPGQuality", True) _AutoItObject_AddMethod($this, "SetTIFColorDepth", "ScreenCapture_SetTIFColorDepth", True) _AutoItObject_AddMethod($this, "SetTIFCompression", "ScreenCapture_SetTIFCompression", True) Return $this EndFunc ;==>ScreenCapture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_Capture ; Description ...: Captures a region of the screen ; Syntax.........: ScreenCapture_Capture([$sFileName = ""[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $iLeft - X coordinate of the upper left corner of the rectangle ; $iTop - Y coordinate of the upper left corner of the rectangle ; $iRight - X coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +width will be used. ; $iBottom - Y coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +height will be used. ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_Capture($this, $sFileName = "", $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $iH, $iW, $hWnd, $hDDC, $hCDC, $hBMP, $aCursor, $aIcon, $hIcon If $iRight = -1 Then $iRight = _WinAPI_GetSystemMetrics($this.ScreenCAPTURECONSTANT_SM_CXSCREEN) If $iBottom = -1 Then $iBottom = _WinAPI_GetSystemMetrics($this.ScreenCAPTURECONSTANT_SM_CYSCREEN) If $iRight < $iLeft Then Return SetError(-1, 0, 0) If $iBottom < $iTop Then Return SetError(-2, 0, 0) $iW = $iRight - $iLeft $iH = $iBottom - $iTop $hWnd = _WinAPI_GetDesktopWindow() $hDDC = _WinAPI_GetDC($hWnd) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, $this.ScreenCAPTURECONSTANT_SRCCOPY) If $fCursor Then $aCursor = _WinAPI_GetCursorInfo() If $aCursor[1] Then $hIcon = _WinAPI_CopyIcon($aCursor[2]) $aIcon = _WinAPI_GetIconInfo($hIcon) _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iLeft, $aCursor[4] - $aIcon[3] - $iTop, $hIcon) _WinAPI_DestroyIcon($hIcon) _WinAPI_DeleteObject($aIcon[4]); <- THIS! _WinAPI_DeleteObject($aIcon[5]); <- THIS! EndIf EndIf _WinAPI_ReleaseDC($hWnd, $hDDC) _WinAPI_DeleteDC($hCDC) If $sFileName = "" Then Return $hBMP $this.SaveImage($sFileName, $hBMP) _WinAPI_DeleteObject($hBMP) EndFunc ;==>ScreenCapture_Capture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_CaptureWnd ; Description ...: Captures a screen shot of a specified window ; Syntax.........: ScreenCapture_CaptureWnd($sFileName, $hWnd[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $hWnd - Handle to the window to be captured ; $iLeft - X coordinate of the upper left corner of the client rectangle ; $iTop - Y coordinate of the upper left corner of the client rectangle ; $iRight - X coordinate of the lower right corner of the rectangle ; $iBottom - Y coordinate of the lower right corner of the rectangle ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. All coordinates are in ; client coordinate mode. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; Credits .......: Thanks to SmOke_N for his suggestion for capturing part of the client window ; =============================================================================================================================== Func ScreenCapture_CaptureWnd($sFileName, $hWnd, $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $tRect $tRect = _WinAPI_GetWindowRect($hWnd) $iLeft += DllStructGetData($tRect, "Left") $iTop += DllStructGetData($tRect, "Top") If $iRight = -1 Then $iRight = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left") If $iBottom = -1 Then $iBottom = DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top") $iRight += DllStructGetData($tRect, "Left") $iBottom += DllStructGetData($tRect, "Top") If $iLeft > DllStructGetData($tRect, "Right") Then $iLeft = DllStructGetData($tRect, "Left") If $iTop > DllStructGetData($tRect, "Bottom") Then $iTop = DllStructGetData($tRect, "Top") If $iRight > DllStructGetData($tRect, "Right") Then $iRight = DllStructGetData($tRect, "Right") If $iBottom > DllStructGetData($tRect, "Bottom") Then $iBottom = DllStructGetData($tRect, "Bottom") Return ScreenCapture_Capture($sFileName, $iLeft, $iTop, $iRight, $iBottom, $fCursor) EndFunc ;==>ScreenCapture_CaptureWnd ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SaveImage ; Description ...: Saves an image to file ; Syntax.........: ScreenCapture_SaveImage($sFileName, $hBitmap[, $fFreeBmp = True]) ; Parameters ....: $sFileName - Full path and extension of the bitmap file to be saved ; $hBitmap - HBITMAP handle ; $fFreeBmp - If True, hBitmap will be freed on a successful save ; Return values .: Success - True ; Failure - False ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: This function saves a bitmap to file, converting it to the image format specified by the file name extension. ; For Windows XP, the valid extensions are BMP, GIF, JPEG, PNG and TIF. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: ScreenCapture_Capture ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SaveImage($this, $sFileName, $hBitmap, $fFreeBmp = True) Local $hClone, $sCLSID, $tData, $sExt, $hImage, $pParams, $tParams, $iResult, $iX, $iY _GDIPlus_Startup() If @error Then Return SetError(-1, -1, False) $sExt = StringUpper(__GDIPlus_ExtractFileExt($sFileName)) $sCLSID = _GDIPlus_EncodersGetCLSID($sExt) If $sCLSID = "" Then Return SetError(-2, -2, False) $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) If @error Then Return SetError(-3, -3, False) Switch $sExt Case "BMP" $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) $hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iX, $iY, $this.giBMPFormat) _GDIPlus_ImageDispose($hImage) $hImage = $hClone Case "JPG", "JPEG" $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $this.giJPGQuality) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData)) Case "TIF", "TIFF" $tParams = _GDIPlus_ParamInit(2) $tData = DllStructCreate("int ColorDepth;int Compression") DllStructSetData($tData, "ColorDepth", $this.giTIFColorDepth) DllStructSetData($tData, "Compression", $this.giTIFCompression) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOLORDEPTH, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "ColorDepth")) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOMPRESSION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Compression")) EndSwitch If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams) $iResult = _GDIPlus_ImageSaveToFileEx($hImage, $sFileName, $sCLSID, $pParams) _GDIPlus_ImageDispose($hImage) If $fFreeBmp Then _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return SetError($iResult = False, 0, $iResult = True) EndFunc ;==>ScreenCapture_SaveImage ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetBMPFormat ; Description ...: Sets the bit format that will be used for BMP screen captures ; Syntax.........: ScreenCapture_SetBMPFormat($iFormat) ; Parameters ....: $iFormat - Image bits per pixel (bpp) setting: ; |0 = 16 bpp; 5 bits for each RGB component ; |1 = 16 bpp; 5 bits for red, 6 bits for green and 5 bits blue ; |2 = 24 bpp; 8 bits for each RGB component ; |3 = 32 bpp; 8 bits for each RGB component. No alpha component. ; |4 = 32 bpp; 8 bits for each RGB and alpha component ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, BMP screen captures default to 24 bpp ; Related .......: ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SetBMPFormat($this, $iFormat) Switch $iFormat Case 0 $this.giBMPFormat = $GDIP_PXF16RGB555 Case 1 $this.giBMPFormat = $GDIP_PXF16RGB565 Case 2 $this.giBMPFormat = $GDIP_PXF24RGB Case 3 $this.giBMPFormat = $GDIP_PXF32RGB Case 4 $this.giBMPFormat = $GDIP_PXF32ARGB Case Else $this.giBMPFormat = $GDIP_PXF24RGB EndSwitch Return $this EndFunc ;==>ScreenCapture_SetBMPFormat ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetJPGQuality ; Description ...: Sets the quality level that will be used for JPEG screen captures ; Syntax.........: ScreenCapture_SetJPGQuality($iQuality) ; Parameters ....: $iQuality - The quality level of the image. Must be in the range of 0 to 100. ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, JPEG screen captures default to a quality level of 100 ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetJPGQuality($this, $iQuality) If $iQuality < 0 Then $iQuality = 0 If $iQuality > 100 Then $iQuality = 100 $this.giJPGQuality = $iQuality Return $this EndFunc ;==>ScreenCapture_SetJPGQuality ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFColorDepth ; Description ...: Sets the color depth used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFColorDepth($iDepth) ; Parameters ....: $iDepth - Image color depth: ; | 0 - Default encoder color depth ; |24 - 24 bit ; |32 - 32 bit ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIFF screen captures default to 24 bits ; Related .......: ScreenCapture_SetTIFCompression ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFColorDepth($this, $iDepth) Switch $iDepth Case 24 $this.giTIFColorDepth = 24 Case 32 $this.giTIFColorDepth = 32 Case Else $this.giTIFColorDepth = 0 EndSwitch Return $this EndFunc ;==>ScreenCapture_SetTIFColorDepth ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFCompression ; Description ...: Sets the compression used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFCompression($iCompress) ; Parameters ....: $iCompress - Image compression type: ; |0 - Default encoder compression ; |1 - No compression ; |2 - LZW compression ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIF screen captures default to LZW compression ; Related .......: ScreenCapture_SetTIFColorDepth ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFCompression($this, $iCompress) Switch $iCompress Case 1 $this.giTIFCompression = $GDIP_EVTCOMPRESSIONNONE Case 2 $this.giTIFCompression = $GDIP_EVTCOMPRESSIONLZW Case Else $this.giTIFCompression = 0 EndSwitch Return $this EndFunc ;==>ScreenCapture_SetTIFCompression #endregion ScreenCapture Object Edited June 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Fainth Posted June 5, 2010 Share Posted June 5, 2010 nice one ! I was reading throu all this just now and ther you come along with something working Link to comment Share on other sites More sharing options...
Phenom Posted June 5, 2010 Author Share Posted June 5, 2010 Which function call do I use now instead of _findBMP()? Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 (edited) Which function call do I use now instead of _findBMP()? If you wanted to run my latest code then just put all of that code into one au3 and hit F5. DOn't forget to substitute your images for mine as per the comment. Everything that you need to know about how to use it is in my latest code. Alternatively, you could put the following code into a file named 'BMPinBMP Object.au3': expandcollapse popup#include-once #include "AutoItObject.au3" #include <GDIPlus.au3> #include <WinAPI.au3> #region BMPinBMP Object Func BMPinBMP() Local $this = _AutoItObject_Create(ScreenCapture()) _AutoItObject_AddProperty($this, "c24RGBFullMatch", $ELSCOPE_PRIVATE, 1) ;Load as 24 bits and full match _AutoItObject_AddProperty($this, "c24RGBPartialMatch", $ELSCOPE_PRIVATE, 2) ;Load as 24 bits and partial match _AutoItObject_AddProperty($this, "c16RGBFullMatch", $ELSCOPE_PRIVATE, 3) ;Load as 16 bits and full match _AutoItObject_AddProperty($this, "c16RGBPartialMatch", $ELSCOPE_PRIVATE, 4) ;Load as 16 bits and partial match _AutoItObject_AddProperty($this, "SuccessArr", $ELSCOPE_PRIVATE) _AutoItObject_AddProperty($this, "BMP1Height", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1Width", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1LineWidth", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP1Data", $ELSCOPE_PRIVATE, 1) _AutoItObject_AddProperty($this, "BMP2Height", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2Width", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2LineWidth", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "BMP2Data", $ELSCOPE_PRIVATE, 2) _AutoItObject_AddMethod($this, "FindBMP", "BMPinBMP_FindBMP") _AutoItObject_AddMethod($this, "GetImage", "BMPinBMP_GetImage", True) Return $this EndFunc ;==>BMPinBMP Func BMPinBMP_FindBMP($this, $BMP1, $BMP2, $MatchType = 1) Local $matchedLines = 0, $foundAtLeft = -1, $foundAtTop = -1 ; $foundAt = "", $matchPossible = False, Local $bestMatchLine = -1, $HighestMatchingLines = -1; For knowing when no match is found where best area is Local $iPos = 1, $iFuzzyDist, $searchFor, $iAbove, $aboveLine If ($MatchType = $this.c24RGBFullMatch) Or ($MatchType = $this.c24RGBPartialMatch) Then Local $imgBytes = 3 Else $imgBytes = 2 EndIf ; Load the bitmap to search in $this.GetImage($BMP1, 1, $imgBytes) $this.BMP1Data = BinaryToString($this.BMP1Data) ; Load the bitmap to find $this.GetImage($BMP2, 2, $imgBytes) ;Make it a string to be able to use string functions for searching $this.BMP2Data = BinaryToString($this.BMP2Data) ;For reference of line where in BMP2FindIn a line of BMP2Find was found If $this.BMP2Height = 0 Then Return SetError(1) ;~ Local $fLine[$BMP2Height]; Line number of found line(s), reLocalmed when second picture size is known ;If exact match check every 1 line else do it more fuzzy (as most likely other lines are unique) If ($MatchType = $this.c24RGBFullMatch) Or ($MatchType = $this.c16RGBFullMatch) Then $iFuzzyDist = 1 Else ;Check fuzzy every 10% of lines $iFuzzyDist = Ceiling(($this.BMP2Height * 0.1)) EndIf Local $bMatchPossible For $i = 0 To $this.BMP2Height - 1 ;Look for each line of the bitmap if it exists in the bitmap to find in ;Minus imgbytes as last bits are padded with unpredictable bytes (24 bits image assumption) or 2 when 16 bits $searchFor = StringMid($this.BMP2Data, 1 + ($i * $this.BMP2LineWidth), ($this.BMP2LineWidth - $imgBytes)) $iPos = StringInStr($this.BMP1Data, $searchFor, 2, 1, $iPos) ;$iPos = StringInStr($this.BMP1Data, $searchFor) ;Look for all lines above if there is also a match ;Not doing it for the lines below as speed is more important and risk of mismatch on lines below is small $iAbove = 1 If $iPos > 0 Then $bMatchPossible = True $matchedLines = 1 ;As first found line is matched we start counting ;Location of the match $foundAtTop = Int($iPos / $this.BMP1LineWidth) - $i $foundAtLeft = Int(Mod($iPos, $this.BMP1LineWidth) / $imgBytes) While $i + $iAbove <= $this.BMP2Height - 1 $searchFor = StringMid($this.BMP2Data, 1 + (($i + $iAbove) * $this.BMP2LineWidth), $this.BMP2LineWidth - $imgBytes) $aboveLine = StringMid($this.BMP1Data, $iPos + ($iAbove * $this.BMP1LineWidth), $this.BMP2LineWidth - $imgBytes) If $aboveLine <> $searchFor Then ;To remember the area with the best match If $matchedLines >= $HighestMatchingLines Then $HighestMatchingLines = $matchedLines ;Best guess of location ;~ $foundAtTop = $fline[$i] + $i - $this.BMP2Height $foundAtTop = Int($iPos / $this.BMP1LineWidth);+ $i - $this.BMP2Height $bestMatchLine = Int($iPos / $this.BMP1LineWidth) EndIf ExitLoop EndIf $matchedLines += 1 $iAbove += $iFuzzyDist WEnd ElseIf $iPos = 0 Then Return SetError(2) EndIf If $bMatchPossible = True Then ExitLoop ;If bMatchPossible is still true most likely we have found the bitmap Next Return StringSplit($bMatchPossible & ";" & $matchedLines & ";" & $foundAtLeft & ";" & $foundAtTop & ";" & $this.BMP2Width & ";" & $this.BMP2Height & ";" & $HighestMatchingLines & ";" & $bestMatchLine, ";", 2) EndFunc ;==>BMPinBMP_FindBMP Func BMPinBMP_GetImage($this, $BMPFile, $image, $imgBytes = 3) _GDIPlus_Startup() If $BMPFile == "SCREEN" Then ; Load the bitmap to search in Local $hbScreen = $this.Capture("", 0, 0, -1, -1, False) Local $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap Else ;try to get a handle Local $handle = WinGetHandle($BMPFile) If @error Then ;Assume its an unknown handle so correct filename should be given $pBitmap = _GDIPlus_BitmapCreateFromFile($BMPFile) Else $hbScreen = $this.CaptureWnd("", $handle, 0, 0, -1, -1, False) $pBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hbScreen); returns memory bitmap EndIf EndIf ;Get $tagGDIPBITMAPDATA structure ;~ ConsoleWrite("Bitmap Width: " & _GDIPlus_ImageGetWidth($pBitmap) & @CRLF ) ;~ ConsoleWrite("Bitmap Height: " & _GDIPlus_ImageGetHeight($pBitmap) & @CRLF) ;~ 24 bits (3 bytes) or 16 bits (2 bytes) comparison If ($imgBytes = 2) Then Local $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF16RGB555) Else $BitmapData = _GDIPlus_BitmapLockBits($pBitmap, 0, 0, _GDIPlus_ImageGetWidth($pBitmap), _GDIPlus_ImageGetHeight($pBitmap), $GDIP_ILMREAD, $GDIP_PXF24RGB) EndIf If @error Then MsgBox(0, "", "Error locking region " & @error) If $image = 1 Then $this.BMP1LineWidth = DllStructGetData($BitmapData, "Stride") ;Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $this.BMP1Width = DllStructGetData($BitmapData, "Width") ;Image width - Number of pixels in one scan line of the bitmap. $this.BMP1Height = DllStructGetData($BitmapData, "Height") ;Image height - Number of scan lines in the bitmap. ;~ Local $PixelFormat = DllStructGetData($BitmapData, "PixelFormat") ;Pixel format - Integer that specifies the pixel format of the bitmap Local $Scan0 = DllStructGetData($BitmapData, "Scan0") ;Scan0 - Pointer to the first (index 0) scan line of the bitmap. Local $pixelData = DllStructCreate("ubyte lData[" & (Abs($this.BMP1LineWidth) * $this.BMP1Height - 1) & "]", $Scan0) $this.BMP1Data = DllStructGetData($pixelData, "lData") ElseIf $image = 2 Then $this.BMP2LineWidth = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $this.BMP2Width = DllStructGetData($BitmapData, "Width");Image width - Number of pixels in one scan line of the bitmap. $this.BMP2Height = DllStructGetData($BitmapData, "Height");Image height - Number of scan lines in the bitmap. ;~ $PixelFormat = DllStructGetData($BitmapData, "PixelFormat");Pixel format - Integer that specifies the pixel format of the bitmap $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap. $pixelData = DllStructCreate("ubyte lData[" & (Abs($this.BMP2LineWidth) * $this.BMP2Height - 1) & "]", $Scan0) $this.BMP2Data = DllStructGetData($pixelData, "lData") EndIf _GDIPlus_BitmapUnlockBits($pBitmap, $BitmapData) _GDIPlus_ImageDispose($pBitmap) _GDIPlus_Shutdown() ;~ _WinAPI_DeleteObject($pBitmap) ;~ _WinAPI_DeleteObject($hbScreen) Return $this EndFunc ;==>BMPinBMP_GetImage #endregion BMPinBMP Object #region ScreenCapture Object ; #INDEX# ======================================================================================================================= ; Title .........: Screen Capture ; AutoIt Version: 3.2.3++ ; Language: English ; Description ...: This module allows you to copy the screen or a region of the screen and save it to file. Depending on the type ; of image, you can set various image parameters such as pixel format, quality and compression. ; Author ........: Paul Campbell (PaulIA) ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;ScreenCapture_Capture ;ScreenCapture_CaptureWnd ;ScreenCapture_SaveImage ;ScreenCapture_SetBMPFormat ;ScreenCapture_SetJPGQuality ;ScreenCapture_SetTIFColorDepth ;ScreenCapture_SetTIFCompression ; =============================================================================================================================== Func ScreenCapture() Local $this = _AutoItObject_Create() _AutoItObject_AddProperty($this, "giBMPFormat", $ELSCOPE_PRIVATE, $GDIP_PXF24RGB) _AutoItObject_AddProperty($this, "giJPGQuality", $ELSCOPE_PRIVATE, 100) _AutoItObject_AddProperty($this, "giTIFColorDepth", $ELSCOPE_PRIVATE, 24) _AutoItObject_AddProperty($this, "giTIFCompression", $ELSCOPE_PRIVATE, $GDIP_EVTCOMPRESSIONLZW) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SM_CXSCREEN", $ELSCOPE_PRIVATE, 0) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SM_CYSCREEN", $ELSCOPE_PRIVATE, 1) _AutoItObject_AddProperty($this, "ScreenCAPTURECONSTANT_SRCCOPY", $ELSCOPE_PRIVATE, 0x00CC0020) _AutoItObject_AddMethod($this, "Capture", "ScreenCapture_Capture", True) _AutoItObject_AddMethod($this, "CaptureWnd", "ScreenCapture_CaptureWnd", True) _AutoItObject_AddMethod($this, "SaveImage", "ScreenCapture_SaveImage", True) _AutoItObject_AddMethod($this, "SetBMPFormat", "ScreenCapture_SetBMPFormat", True) _AutoItObject_AddMethod($this, "SetJPGQuality", "ScreenCapture_SetJPGQuality", True) _AutoItObject_AddMethod($this, "SetTIFColorDepth", "ScreenCapture_SetTIFColorDepth", True) _AutoItObject_AddMethod($this, "SetTIFCompression", "ScreenCapture_SetTIFCompression", True) Return $this EndFunc ;==>ScreenCapture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_Capture ; Description ...: Captures a region of the screen ; Syntax.........: ScreenCapture_Capture([$sFileName = ""[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $iLeft - X coordinate of the upper left corner of the rectangle ; $iTop - Y coordinate of the upper left corner of the rectangle ; $iRight - X coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +width will be used. ; $iBottom - Y coordinate of the lower right corner of the rectangle. If this is -1, the current screen ; +height will be used. ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_Capture($this, $sFileName = "", $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $iH, $iW, $hWnd, $hDDC, $hCDC, $hBMP, $aCursor, $aIcon, $hIcon If $iRight = -1 Then $iRight = _WinAPI_GetSystemMetrics($this.ScreenCAPTURECONSTANT_SM_CXSCREEN) If $iBottom = -1 Then $iBottom = _WinAPI_GetSystemMetrics($this.ScreenCAPTURECONSTANT_SM_CYSCREEN) If $iRight < $iLeft Then Return SetError(-1, 0, 0) If $iBottom < $iTop Then Return SetError(-2, 0, 0) $iW = $iRight - $iLeft $iH = $iBottom - $iTop $hWnd = _WinAPI_GetDesktopWindow() $hDDC = _WinAPI_GetDC($hWnd) $hCDC = _WinAPI_CreateCompatibleDC($hDDC) $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, $this.ScreenCAPTURECONSTANT_SRCCOPY) If $fCursor Then $aCursor = _WinAPI_GetCursorInfo() If $aCursor[1] Then $hIcon = _WinAPI_CopyIcon($aCursor[2]) $aIcon = _WinAPI_GetIconInfo($hIcon) _WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iLeft, $aCursor[4] - $aIcon[3] - $iTop, $hIcon) _WinAPI_DestroyIcon($hIcon) _WinAPI_DeleteObject($aIcon[4]); <- THIS! _WinAPI_DeleteObject($aIcon[5]); <- THIS! EndIf EndIf _WinAPI_ReleaseDC($hWnd, $hDDC) _WinAPI_DeleteDC($hCDC) If $sFileName = "" Then Return $hBMP $this.SaveImage($sFileName, $hBMP) _WinAPI_DeleteObject($hBMP) EndFunc ;==>ScreenCapture_Capture ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_CaptureWnd ; Description ...: Captures a screen shot of a specified window ; Syntax.........: ScreenCapture_CaptureWnd($sFileName, $hWnd[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]) ; Parameters ....: $sFileName - Full path and extension of the image file ; $hWnd - Handle to the window to be captured ; $iLeft - X coordinate of the upper left corner of the client rectangle ; $iTop - Y coordinate of the upper left corner of the client rectangle ; $iRight - X coordinate of the lower right corner of the rectangle ; $iBottom - Y coordinate of the lower right corner of the rectangle ; $fCursor - If True the cursor will be captured with the image ; Return values .: See remarks ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If FileName is not blank this function will capture the screen and save it to file. If FileName is blank, this ; function will capture the screen and return a HBITMAP handle to the bitmap image. In this case, after you are ; finished with the bitmap you must call _WinAPI_DeleteObject to delete the bitmap handle. All coordinates are in ; client coordinate mode. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: _WinAPI_DeleteObject ; Link ..........; ; Example .......; Yes ; Credits .......: Thanks to SmOke_N for his suggestion for capturing part of the client window ; =============================================================================================================================== Func ScreenCapture_CaptureWnd($sFileName, $hWnd, $iLeft = 0, $iTop = 0, $iRight = -1, $iBottom = -1, $fCursor = True) Local $tRect $tRect = _WinAPI_GetWindowRect($hWnd) $iLeft += DllStructGetData($tRect, "Left") $iTop += DllStructGetData($tRect, "Top") If $iRight = -1 Then $iRight = DllStructGetData($tRect, "Right") - DllStructGetData($tRect, "Left") If $iBottom = -1 Then $iBottom = DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top") $iRight += DllStructGetData($tRect, "Left") $iBottom += DllStructGetData($tRect, "Top") If $iLeft > DllStructGetData($tRect, "Right") Then $iLeft = DllStructGetData($tRect, "Left") If $iTop > DllStructGetData($tRect, "Bottom") Then $iTop = DllStructGetData($tRect, "Top") If $iRight > DllStructGetData($tRect, "Right") Then $iRight = DllStructGetData($tRect, "Right") If $iBottom > DllStructGetData($tRect, "Bottom") Then $iBottom = DllStructGetData($tRect, "Bottom") Return ScreenCapture_Capture($sFileName, $iLeft, $iTop, $iRight, $iBottom, $fCursor) EndFunc ;==>ScreenCapture_CaptureWnd ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SaveImage ; Description ...: Saves an image to file ; Syntax.........: ScreenCapture_SaveImage($sFileName, $hBitmap[, $fFreeBmp = True]) ; Parameters ....: $sFileName - Full path and extension of the bitmap file to be saved ; $hBitmap - HBITMAP handle ; $fFreeBmp - If True, hBitmap will be freed on a successful save ; Return values .: Success - True ; Failure - False ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: This function saves a bitmap to file, converting it to the image format specified by the file name extension. ; For Windows XP, the valid extensions are BMP, GIF, JPEG, PNG and TIF. ;+ ; Requires GDI+: GDI+ requires a redistributable for applications that ; run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Me operating systems. ; Related .......: ScreenCapture_Capture ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SaveImage($this, $sFileName, $hBitmap, $fFreeBmp = True) Local $hClone, $sCLSID, $tData, $sExt, $hImage, $pParams, $tParams, $iResult, $iX, $iY _GDIPlus_Startup() If @error Then Return SetError(-1, -1, False) $sExt = StringUpper(__GDIPlus_ExtractFileExt($sFileName)) $sCLSID = _GDIPlus_EncodersGetCLSID($sExt) If $sCLSID = "" Then Return SetError(-2, -2, False) $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) If @error Then Return SetError(-3, -3, False) Switch $sExt Case "BMP" $iX = _GDIPlus_ImageGetWidth($hImage) $iY = _GDIPlus_ImageGetHeight($hImage) $hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iX, $iY, $this.giBMPFormat) _GDIPlus_ImageDispose($hImage) $hImage = $hClone Case "JPG", "JPEG" $tParams = _GDIPlus_ParamInit(1) $tData = DllStructCreate("int Quality") DllStructSetData($tData, "Quality", $this.giJPGQuality) _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData)) Case "TIF", "TIFF" $tParams = _GDIPlus_ParamInit(2) $tData = DllStructCreate("int ColorDepth;int Compression") DllStructSetData($tData, "ColorDepth", $this.giTIFColorDepth) DllStructSetData($tData, "Compression", $this.giTIFCompression) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOLORDEPTH, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "ColorDepth")) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOMPRESSION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Compression")) EndSwitch If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams) $iResult = _GDIPlus_ImageSaveToFileEx($hImage, $sFileName, $sCLSID, $pParams) _GDIPlus_ImageDispose($hImage) If $fFreeBmp Then _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Return SetError($iResult = False, 0, $iResult = True) EndFunc ;==>ScreenCapture_SaveImage ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetBMPFormat ; Description ...: Sets the bit format that will be used for BMP screen captures ; Syntax.........: ScreenCapture_SetBMPFormat($iFormat) ; Parameters ....: $iFormat - Image bits per pixel (bpp) setting: ; |0 = 16 bpp; 5 bits for each RGB component ; |1 = 16 bpp; 5 bits for red, 6 bits for green and 5 bits blue ; |2 = 24 bpp; 8 bits for each RGB component ; |3 = 32 bpp; 8 bits for each RGB component. No alpha component. ; |4 = 32 bpp; 8 bits for each RGB and alpha component ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, BMP screen captures default to 24 bpp ; Related .......: ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func ScreenCapture_SetBMPFormat($this, $iFormat) Switch $iFormat Case 0 $this.giBMPFormat = $GDIP_PXF16RGB555 Case 1 $this.giBMPFormat = $GDIP_PXF16RGB565 Case 2 $this.giBMPFormat = $GDIP_PXF24RGB Case 3 $this.giBMPFormat = $GDIP_PXF32RGB Case 4 $this.giBMPFormat = $GDIP_PXF32ARGB Case Else $this.giBMPFormat = $GDIP_PXF24RGB EndSwitch Return $this EndFunc ;==>ScreenCapture_SetBMPFormat ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetJPGQuality ; Description ...: Sets the quality level that will be used for JPEG screen captures ; Syntax.........: ScreenCapture_SetJPGQuality($iQuality) ; Parameters ....: $iQuality - The quality level of the image. Must be in the range of 0 to 100. ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, JPEG screen captures default to a quality level of 100 ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetJPGQuality($this, $iQuality) If $iQuality < 0 Then $iQuality = 0 If $iQuality > 100 Then $iQuality = 100 $this.giJPGQuality = $iQuality Return $this EndFunc ;==>ScreenCapture_SetJPGQuality ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFColorDepth ; Description ...: Sets the color depth used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFColorDepth($iDepth) ; Parameters ....: $iDepth - Image color depth: ; | 0 - Default encoder color depth ; |24 - 24 bit ; |32 - 32 bit ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIFF screen captures default to 24 bits ; Related .......: ScreenCapture_SetTIFCompression ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFColorDepth($this, $iDepth) Switch $iDepth Case 24 $this.giTIFColorDepth = 24 Case 32 $this.giTIFColorDepth = 32 Case Else $this.giTIFColorDepth = 0 EndSwitch Return $this EndFunc ;==>ScreenCapture_SetTIFColorDepth ; #FUNCTION# ==================================================================================================================== ; Name...........: ScreenCapture_SetTIFCompression ; Description ...: Sets the compression used for TIFF screen captures ; Syntax.........: ScreenCapture_SetTIFCompression($iCompress) ; Parameters ....: $iCompress - Image compression type: ; |0 - Default encoder compression ; |1 - No compression ; |2 - LZW compression ; Return values .: ; Author ........: Paul Campbell (PaulIA) ; Modified.......: ; Remarks .......: If not explicitly set, TIF screen captures default to LZW compression ; Related .......: ScreenCapture_SetTIFColorDepth ; Link ..........; ; Example .......; ; =============================================================================================================================== Func ScreenCapture_SetTIFCompression($this, $iCompress) Switch $iCompress Case 1 $this.giTIFCompression = $GDIP_EVTCOMPRESSIONNONE Case 2 $this.giTIFCompression = $GDIP_EVTCOMPRESSIONLZW Case Else $this.giTIFCompression = 0 EndSwitch Return $this EndFunc ;==>ScreenCapture_SetTIFCompression #endregion ScreenCapture Object And then put the following code into your main program: #include "BMPinBMP Object.au3" _AutoItObject_Startup() Global $BMPinBMP = BMPinBMP() Global $result = $BMPinBMP.FindBMP("image1.bmp", "image2.bmp", 1) ; substitute your own images here If IsArray($result) Then Global $resultArr[8] = ["Possible Match ", "Matched Lines ", "Found at left ", "Found at top ", "2nd BMP Width ", "2nd BMP Height ", "Highest Matching Lines ", "Best match line "] For $i = 0 To UBound($result) - 1 ConsoleWrite($resultArr[$i] & $result[$i] & @CRLF) Next EndIf $BMPinBMP = 0 _AutoItObject_Shutdown() Edited June 5, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
jaberwacky Posted June 5, 2010 Share Posted June 5, 2010 OK, something is screwy it only works for some of my bitmaps but not others. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Fainth Posted June 6, 2010 Share Posted June 6, 2010 Did you try bitmaps that have the first line complete same color ? Link to comment Share on other sites More sharing options...
jaberwacky Posted June 6, 2010 Share Posted June 6, 2010 (edited) Did you try bitmaps that have the first line complete same color ?No, that's a prerequisite? What I did is to take a bitmap picture, crop out a section of it, save that into a new bitmap. I then tried to find the cropped section in the bigger bitmap. That works fine for that one and only bitmap. So I guess it's possible that my original bmp and the cropped bmp both have the same color at the top?edit* Ah so yes, that is a prerequisite! Sheesh, that seems kinda unusual. Edited June 6, 2010 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Fainth Posted June 6, 2010 Share Posted June 6, 2010 (edited) I tried to use this for a Patternsearchengine but then wrote my own as a spin-off from it since i had alot of trouble with selections that had their first lines beeing singlecolor. Thats some time ago, i check if i can dig something up from my old Harddrive. Edited June 6, 2010 by Fainth Link to comment Share on other sites More sharing options...
jaberwacky Posted June 6, 2010 Share Posted June 6, 2010 I tried to use this for a Patternsearchengine but then wrote my own as a spin-off from it since i had alot of trouble with selections that had their first lines beeing singlecolor. Thats some time ago, i check if i can dig something up from my old Harddrive.Cool, that'd be awesome. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Phenom Posted June 6, 2010 Author Share Posted June 6, 2010 OK, something is screwy it only works for some of my bitmaps but not others.When I tested it an array wasn't returned to $result. I just got $result = 1. Link to comment Share on other sites More sharing options...
jaberwacky Posted June 8, 2010 Share Posted June 8, 2010 When I tested it an array wasn't returned to $result. I just got $result = 1.I believe that can mean one of two things:1) The image wasn't found2) The top line of both images weren't the sameNumber 2 is the most likely culprit and seems like a bug in the program. I am waiting on fainth to see if he can dig up some of his old scripts. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
junkew Posted June 9, 2010 Share Posted June 9, 2010 Let me know what you feel is a bug in findBMP coding then I can explain or fix. The main subtle problems are that its looking for an exact match if it doesn't have an exact match it will return false but the other values will indicate how many lines of the comparison matched and based on that you still can decide to see it as a positive match. differences are - frequently on rounded corners and then there is a different background - frequently on clocks, times, highlighted areas issues are frequently in - not having GDIPLUS in the right location (or not installed at all) FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
junkew Posted June 9, 2010 Share Posted June 9, 2010 This has a function that finds a BMP within another BMP. Use it like this: $result = _FindBMP($imageToSearch, $imageToFind) $result[1] will hold True if found, false otherwise. If found, then $result[3] will hold the x-coordinate and $result[4] will hold the y-coordinate of the location where the image was found (I think). It doesn't work for me. Can anyone get it to work? This file is based off of http://www.autoitscript.com/forum/index.php?showtopic=66545 The returned values are $bMatchPossible = Could a match be possible $matchedLines = The number of matched lines (if its 1 previous returnvalue probably better to set it at False $foundAtLeft $foundAtTop $bmp2width $BMP2Height $HighestMatchingLines $bestMatchLine FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets 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