Jump to content

Can anyone get this to work?


Recommended Posts

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)

Awesome, so you're the author? That's sweet. Fainth pointed out that the script only seems to find BMPs if the top line of both BMPs are the same. I did some small tests and I think he is right. I took a bmp from which I cut out a section from the middle of the bmp and then I cut out a section from the very top of the bmp. The only time the script reports a find is when I look for the section that I cropped from the top. Is that proper behavior?

Edited by jaberwocky6669
Link to comment
Share on other sites

  • Replies 40
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

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)

It's a little bit slow for my purposes, since it searches the entire screen. Could it be modified so that only a section of the screen can be specified for the search?

Link to comment
Share on other sites

It's a little bit slow for my purposes, since it searches the entire screen. Could it be modified so that only a section of the screen can be specified for the search?

The original post for findBMP is here http://www.autoitscript.com/forum/index.php?showtopic=66545

read that thread and you understand more of the details

There are different ways of speeding things up.

I assume you use findBMP("SCREEN","yourpicture")

You can use

findBMP("[ACTIVE]","yourpicture") to only search in an active window

or use first

_ScreenCapture_Capture (see help for usage) to save an screen area to file (this is very quick) and use then the 2 bitmaps you have to compare

Link to comment
Share on other sites

Awesome, so you're the author? That's sweet. Fainth pointed out that the script only seems to find BMPs if the top line of both BMPs are the same. I did some small tests and I think he is right. I took a bmp from which I cut out a section from the middle of the bmp and then I cut out a section from the very top of the bmp. The only time the script reports a find is when I look for the section that I cropped from the top. Is that proper behavior?

add the bmp's to the post then I will check

Link to comment
Share on other sites

findTester(@tempdir & "\" & "screencap.bmp",@tempdir & "\" & "ks.bmp",$c24RGBPartialMatch) ;Find the Ks

will do the trick (save the files you attached in %temp%)

Script copy paste at the bottom and run in SCITE

I added the demo for the calculator and output should be something like below

>"C:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "H:\CTS\tests\findbmp2.au3" /autoit3dir "C:\Program Files\AutoIt3" /UserParams

+>21:05:13 Starting AutoIt3Wrapper v.1.10.1.14 Environment(Language:0413 Keyboard:00020409 OS:WIN_XP/Service Pack 3 CPU:X86 ANSI)

>Running AU3Check (1.54.19.0) from:C:\Program Files\AutoIt3

+>21:05:13 AU3Check ended.rc:0

>Running:(3.3.6.0):C:\Program Files\AutoIt3\autoit3.exe "H:\CTS\tests\findbmp2.au3"

Saving calculator window 270.368966727151 milliseconds

Saving backspacebutton 12.4119965380464 milliseconds

Saving 0-button 12.3177124373022 milliseconds

Saving 1-button 12.339076299987 milliseconds

Saving 2-button 12.5508997403535 milliseconds

Saving 3-button 12.6476620117426 milliseconds

Saving 4-button 31.4894654356013 milliseconds

Saving 5-button 18.0730378642821 milliseconds

Saving 6-button 12.403707899336 milliseconds

Saving 7-button 12.3783888549154 milliseconds

Saving 8-button 14.9442338088507 milliseconds

Saving 9-button 12.7914921487838 milliseconds

Saving full screen took 149.761209411434 milliseconds

0 BACKSPACE.bmp

True;13;271;428;73;30;-1;-1;17 BACKSPACE.bmp in SCREEN ** matchtype 2 time elapsed: 1056.52249167093 milliseconds

True;13;48;87;73;30;-1;-1;17 BACKSPACE.bmp in [ACTIVE] ** matchtype 2 time elapsed: 53.223209792383 milliseconds

1 0.bmp

True;19;280;562;37;30;9;464;1 0.bmp in SCREEN ** matchtype 2 time elapsed: 1120.10529150919 milliseconds

True;19;57;221;37;30;9;123;1 0.bmp in [ACTIVE] ** matchtype 2 time elapsed: 58.3368213518327 milliseconds

2 1.bmp

True;20;280;529;37;30;9;464;1 1.bmp in SCREEN ** matchtype 2 time elapsed: 1208.43248889735 milliseconds

True;20;57;188;37;30;9;123;1 1.bmp in [ACTIVE] ** matchtype 2 time elapsed: 55.3522671451915 milliseconds

3 2.bmp

True;20;319;529;37;30;9;464;1 2.bmp in SCREEN ** matchtype 2 time elapsed: 1109.43714382145 milliseconds

True;20;96;188;37;30;9;123;1 2.bmp in [ACTIVE] ** matchtype 2 time elapsed: 55.9108406599098 milliseconds

4 3.bmp

True;18;358;529;37;30;9;464;1 3.bmp in SCREEN ** matchtype 2 time elapsed: 1109.64861304649 milliseconds

True;18;135;188;37;30;9;123;1 3.bmp in [ACTIVE] ** matchtype 2 time elapsed: 56.1307161498799 milliseconds

5 4.bmp

True;20;280;497;37;30;9;464;1 4.bmp in SCREEN ** matchtype 2 time elapsed: 1167.3247492924 milliseconds

True;20;57;156;37;30;9;123;1 4.bmp in [ACTIVE] ** matchtype 2 time elapsed: 55.0261310663552 milliseconds

True;3;672;221;43;59;22;254;34 ks.bmp in screencap.bmp ** matchtype 2 time elapsed: 669.776453368889 milliseconds

+>21:05:25 AutoIT3.exe ended.rc:0

+>21:05:26 AutoIt3Wrapper Finished

>Exit code: 0 Time: 13.576

The full script

Opt('MustDeclareVars', 1)
;#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <string.au3>

;~ Constants for type of picture matching
Const $c24RGBFullMatch = 1 ;Load as 24 bits and full match
Const $c24RGBPartialMatch = 2 ;Load as 24 bits and partial match
Const $c16RGBFullMatch = 3 ;Load as 16 bits and full match
Const $c16RGBPartialMatch = 4 ;Load as 16 bits and partial match

; ** Example start **
;~ Executable name of the calculator
Const $cCalculatorExe="calc.exe"

;Global Const $Bitmap12Filename = @TempDir & "\wordgt2.jpg"
;Global Const $Bitmap12Filename = @TempDir & "\t.bmp"
; Screen samples
Global $Bitmap1Filename = @tempdir & "\FULLSCREEN.BMP"  ;Full screen to search in
Global $Bitmap2Filename = @tempdir & "\CALCULATOR.BMP"  ;Calculator window to search in
Global $Bitmap3Filename = @tempdir & "\BACKSPACE.BMP"  ;Calculator window to search in

;~ ; All bitmaps we want to search in abouve screens
;~ Global $BitmapFileNamesScreen[22] = ["CALCULATOR.BMP", "BACKSPACE.bmp", _
;~      "7WDS_BW.bmp","SEVEN_BW.bmp","CAT_BW.bmp", _
;~      "AUTOIT3.bmp", _ ;Make sure the homepage of autoit with 3 is visible
;~      "six_control_codes.bmp","control_code_3.bmp","control_code_5.bmp", _
;~      "blueenvelope.bmp","gray.bmp","car.bmp", _
;~      "0.bmp","1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp","7.bmp","8.bmp","9.bmp"]
Global $BitmapFileNamesScreen[6] = ["CALCULATOR.BMP", "BACKSPACE.bmp", _
        "blueenvelope.bmp","white.bmp","car.bmp", "1.bmp"]

;~ Global $BitmapFileNamesCalculator[11] = ["BACKSPACE.bmp", "0.bmp","1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp","7.bmp","8.bmp","9.bmp"]
Global $BitmapFileNamesCalculator[6] = ["BACKSPACE.bmp", "0.bmp","1.bmp","2.bmp","3.bmp","4.bmp"]

Local $calcHWND, $tBeginTime, $pos, $aWinPos, $aWinCSize, $start
Local $pBitmap, $BitmapData, $pixelFormat
Local $x

Opt("WinTitleMatchMode", 4) ;Matching windows by advanced options

; Initialize GDI+ library
_GDIPlus_Startup()

;Calculator, make sure its started
$calcHWND = WinGetHandle("[CLASS:SciCalc]")
If $calcHWND = "" Then
    Run($cCalculatorExe)
    Sleep(2000)
    $calcHWND = WinGetHandle("[CLASS:SciCalc]")
EndIf

;Capture the calculator screen
$tBeginTime = TimerInit()
WinActivate($calcHWND)
WinMove("[ACTIVE]", "", 223, 341)

_ScreenCapture_CaptureWnd($Bitmap2Filename, $calcHWND, 0, 0, -1, -1, False)
ConsoleWrite("Saving calculator window " & TimerDiff($tBeginTime) & " milliseconds " & @LF)

;Capture an area within the calculator area backspace
$tBeginTime = TimerInit()
$pos = ControlGetPos("", "", "[CLASS:Button; TEXT:BACKSPACE]")
$aWinPos = WinGetPos($calcHWND)
$aWinCSize = WinGetClientSize($calcHWND)
;Q&D calculation of offsets to capture
_ScreenCapture_Capture($Bitmap3Filename, ($aWinPos[0] + $pos[0]) + ($aWinPos[2] - $aWinCSize[0]) - 3, ($aWinPos[1] + $pos[1]) + ($aWinPos[3] - $aWinCSize[1]) - 3, $aWinPos[0] + $pos[0] + $pos[2] + 3, ($aWinPos[1] + $pos[1]) + ($aWinPos[3] - $aWinCSize[1]) + $pos[3] - 3, False)
ConsoleWrite("Saving backspacebutton " & TimerDiff($tBeginTime) & " milliseconds " & @LF)

;Capture all numeric buttons of the calculator
For $i = 0 To 9
    $tBeginTime = TimerInit()
    $pos = ControlGetPos("", "", "[CLASS:Button; TEXT:" & StringStripWS($i, 3) & "]")
    $aWinPos = WinGetPos($calcHWND)
    $aWinCSize = WinGetClientSize($calcHWND)
    ;Q&D calculation of offsets to capture
    _ScreenCapture_Capture(@TempDir & "\" & StringStripWS($i, 3) & ".bmp", ($aWinPos[0] + $pos[0]) + ($aWinPos[2] - $aWinCSize[0]) - 3, ($aWinPos[1] + $pos[1]) + ($aWinPos[3] - $aWinCSize[1]) - 3, $aWinPos[0] + $pos[0] + $pos[2] + 3, ($aWinPos[1] + $pos[1]) + ($aWinPos[3] - $aWinCSize[1]) + $pos[3] - 3, False)
    ConsoleWrite("Saving " & StringStripWS($i, 3) & "-button " & TimerDiff($tBeginTime) & " milliseconds " & @LF)
Next

; Capture full screen
$tBeginTime = TimerInit()
_ScreenCapture_Capture($Bitmap1Filename, 0, 0, -1, -1, False)
ConsoleWrite("Saving full screen took " & TimerDiff($tBeginTime) & " milliseconds " & @LF)

;~ Just a little helper to get the name of the file 
Func fileGetname($f)
    Local $i
    $i = StringInStr($f, "\", False, -1)
    If $i > 0 Then
        Return StringMid($f, $i + 1)
    Else
        Return $f
    EndIf
EndFunc   ;==>filegetname

;Do the actual find
Func FindTester($BMP1, $BMP2, $Bool)
    Local $tResult
    $start = TimerInit()
    $tResult = findBMP($BMP1, $BMP2, $Bool)
    ConsoleWrite($tResult & @tab & filegetname($BMP2) & " in " & filegetname($BMP1) & @tab & " ** matchtype " & $Bool & " time elapsed: " & TimerDiff($start) & "  milliseconds" & @LF)
EndFunc   ;==>FindTester

;Find all the different bmp files in the 2 screenshots made or in SCREEN or ACTIVE
;~ Make sure the autoit homepage is active in the browser and visible on screen if you want to find the 3
;~ Not very usefull to find full screen and tricky as screen is most likely changed (clock, output from application etc.)

for $i=0 to ubound($BitmapFileNamesScreen)-1
;~  consolewrite($i & @tab & $bitmapfilenamesScreen[$i] &@crlf)
;~  findTester("SCREEN",@tempdir & "\" & $bitmapFilenamesScreen[$i],$c24RGBFullMatch) 
;~      findTester("SCREEN",@tempdir & "\" & $bitmapFilenamesScreen[$i],$c24RGBPartialMatch) 
;~      findTester("SCREEN",@tempdir & "\" & $bitmapFilenamesScreen[$i],$c16RGBFullMatch) 
;~      findTester("SCREEN",@tempdir & "\" & $bitmapFilenamesScreen[$i],$c16RGBPartialMatch) 
;~      findTester("[ACTIVE]",@tempdir & "\" & $bitmapFilenamesScreen[$i],$c24RGBFullMatch) ;Find the bitmap in the active screen
Next

for $i=0 to ubound($BitmapFileNamesCalculator)-1
    consolewrite($i & @tab & $bitmapfilenamesCalculator[$i] &@crlf)
    findTester("SCREEN",@tempdir & "\" & $bitmapfilenamesCalculator[$i],$c24RGBPartialMatch)
    winactivate($calcHWND) ;Make sure calculator is active on the screen    
    findTester("[ACTIVE]",@tempdir & "\" & $bitmapFilenamesCalculator[$i],$c24RGBPartialMatch) ;Find the backspace button
Next

findTester(@tempdir & "\" & "screencap.bmp",@tempdir & "\" & "ks.bmp",$c24RGBPartialMatch) ;Find the Ks


_GDIPlus_Shutdown()

;** Example end **

;===============================================================================
; 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):
;
;===============================================================================

Func findBMP($BMP1, $BMP2, $MatchType = $c24RGBFullMatch)
    Dim $splitMeOn  
;~  , $picLines[1] ;Line number of found line(s), redimmed when second picture size is known
    Dim $vCount, $vLine, $prevVCount ;For determining the most unique line in the picture
    Dim $BMP1Data = "", $BMP1Width = 0, $BMP1Height = 0, $BMP1LineWidth = 0
    Dim $BMP2Data = "", $BMP2Width = 0, $BMP2Height = 0, $BMP2LineWidth = 0
    Dim $foundAt = "", $matchPossible = False, $matchedLines = 0, $foundAtLeft = -1, $foundAtTop = -1
    Dim $bestMatchLine = -1, $HighestMatchingLines = -1 ; For knowing when no match is found where best area is
    Dim $iPos = 1
    Dim $imgBytes, $padBytes1, $padBytes2, $splitpos
    Dim $sLineToSearch, $vCount
    dim $dataAbove
    dim $sData
    
    Local $iFuzzyDist, $iAbove, $bMatchPossible, $aboveLine
    Local $j, $imgBits

    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

    ;Determine bytes used for padding on 4 byte boundary
    $padBytes1 = $BMP1LineWidth - ($BMP1Width * $imgBytes)
    $padBytes2 = $BMP2LineWidth - ($BMP2Width * $imgBytes)
    
    ;Get all of the picturelines of 2nd bitmap in a seperate array
    Dim $picLines[$BMP2Height]

    $vline=0

    for $i=0 to $BMP2Height-1
        $picLines[$i]=StringMid($BMP2Data, 1 + ($i * $BMP2LineWidth), ($BMP2LineWidth - $padBytes2))
        
        ;~  ;Find line with most variation
        $sLineToSearch=$picLines[$i]
        $vCount=0
        For $j=2 to (Stringlen($slineToSearch)/$imgBytes) step $imgBytes
            if stringmid($slinetosearch,$j,$imgBytes) <> stringmid($slinetosearch,$j-$imgBytes,$imgBytes) then
                $vCount=$vcount+1
            endif
        Next
        if $vcount > $prevVCount Then
                $prevVCount=$vcount
                $vLine=$i
        endIf
    Next
;~  consolewrite($vLine & "; " & $vcount & @crlf)
    
    ;For debugging
;~  dumpHex("test", $BMP1Data, $BMP1Height, $BMP1LineWidth)
;~  dumpHex("test", $BMP2Data, $BMP2Height, $BMP2LineWidth)
    
    ;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
        $i=0 ;Start searching at the first line 
    Else
        ;At least make sure we search at least 10% or 4 lines of the total lines if we are using the most unique line to search
        if ($vline < ceiling($bmp2height*0.90)) or ($vline < ($bmp2height-4)) Then
            ;Check fuzzy every 10% of lines left over from starting most unique line
            $iFuzzyDist = 1; Ceiling((($BMP2Height-$vline) * 0.1))
            $i = $vline ;Start searching at the line thats most unique
;~          consolewrite("Fuzzy find < 0.75 " & $vline & ":")
        Else
            $iFuzzyDist = Ceiling(($BMP2Height * 0.2))
            $i= 0 ;Start searching at line 0 to not start searching to high
            consolewrite("Fuzzy find > 0.75 " & $vline & ":")
        endIf           
    EndIf

;~  $tBeginTime = TimerInit()
    ;Look for each line of the bitmap if it exists in the bitmap to find in
;~  For $i = 0 To $BMP2Height - 1
    while $i <= $bmp2height-1   
        ;Minus imgbytes as last bits are padded with unpredictable bytes (24 bits image assumption) or 2 when 16 bits
        $sLineToSearch= $piclines[$i] ; StringMid($BMP2Data, 1 + ($i * $BMP2LineWidth), ($BMP2LineWidth - $padBytes2))
        $iPos = StringInStr($BMP1Data, $sLineToSearch, 2, 1, $iPos)

;~  ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iPos = ' & $iPos & @CRLF & '>Error code: ' & @error & $i & ";ipos " & $iPos & ";" & _StringToHex($sLineToSearch) & @CRLF) ;### Debug Console

        ;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) + 1 - $i
            $foundAtLeft = Int(Mod($iPos, $BMP1LineWidth) / $imgBytes)
        Else
            $bMatchPossible = False
            ExitLoop
        EndIf

        ;Reduce the size of the scanning string tremendously to speed things up
;~      $dataAbove=StringMid($BMP1Data, $iPos, ($BMP2Height - $i) * $BMP1LineWidth)
        
        While (($i + $iAbove) <= ($BMP2Height - 1)) And ($bMatchPossible = True)
            $sLineToSearch=  $piclines[$i+$iAbove] ;StringMid($BMP2Data, 1 + (($i + $iAbove) * $BMP2LineWidth), ($BMP2LineWidth - $padBytes2))
             $aboveLine = StringMid($BMP1Data, $iPos + ($iAbove * $BMP1LineWidth), StringLen($sLineToSearch)) ;Previous line calculates size of string, Be aware of padding.
;~          $aboveLine = StringMid($dataAbove, $iAbove * $BMP1LineWidth, StringLen($sLineToSearch)) ;Previous line calculates size of string, Be aware of padding.

            If $aboveLine <> $sLineToSearch Then
                $bMatchPossible = False
                ;To remember the area with the best match
                If $matchedLines >= $HighestMatchingLines Then
                    $HighestMatchingLines = $matchedLines
                    
                    ;Best guess of location
;~                  $foundAtTop = $picLines[$i] + $i - $BMP2Height
                    $foundAtTop = Int($iPos / $BMP1LineWidth) + 1 ;+ $i - $BMP2Height
                    $foundAtLeft = Int(Mod($iPos, $BMP1LineWidth) / $imgBytes)
                    $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($tBeginTime) / 1000 & "  seconds" & @LF)
            ;           MouseMove($foundatleft,$foundatTop)
            ExitLoop
        Else
;~          consolewrite("i not matched " & $ipos & " " & $matchedlines & @crlf )
        EndIf

;~  Next
    $i=$i+1
    WEnd
    ;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 & ";" & $vline
EndFunc   ;==>findBMP

Func GetImage($BMPFile, ByRef $BMPDataStart, ByRef $Width, ByRef $Height, ByRef $Stride, $imgBytes = 3)
    Local $Scan0, $pixelData, $hbScreen, $pBitmap, $pBitmapCap, $handle

    ; 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
        $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.
    $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)
    _WinAPI_DeleteObject($pBitmap)

EndFunc   ;==>GetImage

Func dumpHex($sFname, $bmData, $h, $w)
    Local $i, $tLine
    
    For $i = 0 To $h - 1
        $tLine = StringMid($bmData, 1 + ($i * $w), $w)
        ConsoleWrite(StringFormat("%06s;", 1 + ($i * $w)) & _StringToHex($tLine) & ";")
        ConsoleWrite(@CRLF)
    Next
EndFunc   ;==>dumpHex
Link to comment
Share on other sites

for lenas eyes it works on my system

see above post for sourcecode and add the following 2 lines (after you save the files to %temp%)

findTester(@tempdir & "\" & "lena.bmp",@tempdir & "\" & "eyes.bmp",$c24RGBPartialMatch) ;Find the eyes of lena

findTester(@tempdir & "\" & "lena.bmp",@tempdir & "\" & "eyes top.bmp",$c24RGBPartialMatch) ;Find the eyes of lena

True;38;235;254;128;38;-1;-1;0 eyes.bmp in lena.bmp ** matchtype 2 time elapsed: 190.717112276235 milliseconds

True;290;239;1;119;290;-1;-1;0 eyes top.bmp in lena.bmp ** matchtype 2 time elapsed: 288.582391488139 milliseconds

Link to comment
Share on other sites

for lenas eyes it works on my system

see above post for sourcecode and add the following 2 lines (after you save the files to %temp%)

findTester(@tempdir & "\" & "lena.bmp",@tempdir & "\" & "eyes.bmp",$c24RGBPartialMatch) ;Find the eyes of lena

findTester(@tempdir & "\" & "lena.bmp",@tempdir & "\" & "eyes top.bmp",$c24RGBPartialMatch) ;Find the eyes of lena

True;38;235;254;128;38;-1;-1;0 eyes.bmp in lena.bmp ** matchtype 2 time elapsed: 190.717112276235 milliseconds

True;290;239;1;119;290;-1;-1;0 eyes top.bmp in lena.bmp ** matchtype 2 time elapsed: 288.582391488139 milliseconds

That doesn't work for me either. This is what I get:

False;0;-1;-1;128;38;-1;-1;0 eyes.bmp in lena.bmp ** matchtype 2 time elapsed: 146.778692525144 milliseconds

False;0;-1;-1;119;290;-1;-1;0 eyes top.bmp in lena.bmp ** matchtype 2 time elapsed: 213.216642902082 milliseconds

Link to comment
Share on other sites

I can't get it to work with these files. Can you get it to work?

You wont get that to work, for one quite apparent reason.

the pictures do not match, there is some kind of artifacts in the smaller image you are trying to find, that is not in the larger picture.

edit or visa versa

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

You wont get that to work, for one quite apparent reason.

the pictures do not match, there is some kind of artifacts in the smaller image you are trying to find, that is not in the larger picture.

edit or visa versa

I don't see how that is possible. How are you able to detect the artifacts?

Link to comment
Share on other sites

zoom in on the larger picture to the leg of the king.

Now look at the leg of the king in the other picture.

These functions rely on pixels and there colours as far as I can work out, so it's not going to find a picture with so much difference.

Use your window info tool to see the differences.

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

Did you copy / paste the source and run the script?

What kind of results did you get for the calculator and its buttons? As calculator is simple and straight forward you first need to have proof that the functions are working on the calculator. If thats not the case you know something is not the same as on my system.

The function works checking line by line but if you do a partial match it will skip some lines

As it works on my system with the pictures attached in the posting I am 98% sure that the artefacts are not there

The intention of the functions I wrote where only to recognize textboxes, icons, hotspots that are not recognizable other ways.

It was not intended to match on shading variations etc. in photos or in games although with the concepts in the source code you can come a long way.

Comment out those 2 lines (make sure your bitmaps are not to large) to see the pictures hexadecimal and find out if the pattern can be found in the other pattern (use a good text editor for that)

;For debugging

;~ dumpHex("test", $BMP1Data, $BMP1Height, $BMP1LineWidth)

;~ dumpHex("test", $BMP2Data, $BMP2Height, $BMP2LineWidth)

Link to comment
Share on other sites

zoom in on the larger picture to the leg of the king.

Now look at the leg of the king in the other picture.

These functions rely on pixels and there colours as far as I can work out, so it's not going to find a picture with so much difference.

Use your window info tool to see the differences.

At the moment you zoom in your system will change the pixels. Only way to do that on a proper level is using tools like GIMP. Don't trust what microsoft windows shows you on zooming in. As the pictures are from different size zooming can be done differently and heavily depends on the tool you use to zoom.

Link to comment
Share on other sites

If you look closely at all of the cards in the large picture, you will see they all have random colours in them, its pretty clear what the message is, and certainly nothing to do with zoom, lol.

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

Did you copy / paste the source and run the script?

What kind of results did you get for the calculator and its buttons? As calculator is simple and straight forward you first need to have proof that the functions are working on the calculator. If thats not the case you know something is not the same as on my system.

The function works checking line by line but if you do a partial match it will skip some lines

As it works on my system with the pictures attached in the posting I am 98% sure that the artefacts are not there

The intention of the functions I wrote where only to recognize textboxes, icons, hotspots that are not recognizable other ways.

It was not intended to match on shading variations etc. in photos or in games although with the concepts in the source code you can come a long way.

Comment out those 2 lines (make sure your bitmaps are not to large) to see the pictures hexadecimal and find out if the pattern can be found in the other pattern (use a good text editor for that)

;For debugging

;~ dumpHex("test", $BMP1Data, $BMP1Height, $BMP1LineWidth)

;~ dumpHex("test", $BMP2Data, $BMP2Height, $BMP2LineWidth)

I tried your code before I posted here. It was all in a zip file with the necessary pictures. I recall that there was a problem recognizing the calculator because the calculator looks different in Windows 7. I remember that there were a few successes, but most were failures.

Nevertheless, I tried the code you posted here, and I got this error on line 68:

Subscript used with non-Array variable.:

_ScreenCapture_Capture($Bitmap3Filename, ($aWinPos[0] + $pos[0]) + ($aWinPos[2] - $aWinCSize[0]) - 3, ($aWinPos[1] + $pos[1]) + ($aWinPos[3] - $aWinCSize[1]) - 3, $aWinPos[0] + $pos[0] + $pos[2] + 3, ($aWinPos[1] + $pos[1]) + ($aWinPos[3] - $aWinCSize[1]) + $pos[3] - 3, False)

_ScreenCapture_Capture($Bitmap3Filename, ($aWinPos[0] + $pos^ ERROR

So I just moved the line I was interested in to the top and wrote exit underneath to get around that.

How does the partial match decide which lines to skip? Wouldn't it be better if partial match checked every line, and then used some predefined match percentage to determine if the image matches? Or better yet, what if the user could specify the match percentage?

Edited by Phenom
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...