|
把SSS文件解压放到TMP临时文件夹然后屏幕分辨率调到1280*1024进行调试,代码来自主站
我都调用别人的插件来找图,本人英文差,不好解决下面这段代码
这段代码应该是找图核心代码吧,
Opt('MustDeclareVars', 1)
;#include <GUIConstants.au3>
#include <GDIPlus.au3>
#Include <ScreenCapture.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 **
; Screen samples
Global Const $Bitmap1Filename = @TempDir & "\FULLSCREEN.bmp"
Global Const $Bitmap2Filename = @TempDir & "\CALCULATOR.bmp"
Global Const $Bitmap3Filename = @TempDir & "\BACKSPACE.bmp"
;BMP samples
Global Const $Bitmap4Filename = @TempDir & "\7WDS_BW.bmp"
Global Const $Bitmap5Filename = @TempDir & "\SEVEN_BW.bmp"
Global Const $Bitmap6Filename = @TempDir & "\CAT_BW.bmp"
Global Const $Bitmap7Filename = @TempDir & "\AUTOIT3.bmp" ;Make sure the homepage of autoit with 3 is visible
local $calcHWND, $begin, $pos, $aWinPos, $aWinCSize, $start
local $pBitmap, $BitmapData, $pixelFormat
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("calc.exe")
sleep(2000)
$calcHWND = WinGetHandle("[CLASS:SciCalc]")
EndIf
;Capture the calculator screen
$begin = TimerInit()
winactivate($calcHWND)
_ScreenCapture_CaptureWnd($Bitmap2Filename, $calcHWND,0,0,-1,-1,False)
ConsoleWrite("Saving calculator window " & TimerDiff($begin) & " milliseconds " & @LF)
winmove("[ACTIVE]","",223,341)
;Capture an area within the calculator area backspace
$begin = TimerInit()
$pos=controlgetpos("","","[CLASS:Button; TEXT:BACKSPACE]");;;;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($begin) & " milliseconds " & @LF)
; Capture full screen
$begin = TimerInit()
_ScreenCapture_Capture($Bitmap1Filename,0,0,-1,-1,False)
ConsoleWrite("Saving full screen took " & TimerDiff($begin) & " milliseconds " & @LF)
func filegetname($f)
local $i
$i=stringinstr($f,"\",false,-1)
if $i > 0 Then
return stringmid($f,$i+1)
Else
return $f
EndIf
EndFunc
;Do the actual find
Func FindTester($BMP1, $BMP2, $Bool)
local $tResult
$start = TimerInit()
$tResult=findBMP($BMP1,$BMP2, $Bool)
ConsoleWrite($tResult & " " & FileGetName($BMP2) & " in " & FileGetName($BMP1) & " ** matchtype " & $Bool & " time elapsed: " & TimerDiff($start) & " milliseconds" & @LF)
EndFunc
; Not very usefull to find full screen and tricky as screen is most likely changed (clock, output from application etc.)
; findTester("SCREEN",$Bitmap1Filename,TRUE);Find the full screen itself
; findTester($Bitmap1Filename,$Bitmap1Filename,$c24RGBFullMatch);Find the full screen itself 31 seconds
findTester($Bitmap1Filename,$Bitmap1Filename,$c24RGBPartialMatch);Find the full screen itself 2.8529088255245 seconds
; findTester($Bitmap1Filename,$Bitmap1Filename,$c16RGBFullMatch);Find the full screen itself 21 seconds
findTester($Bitmap1Filename,$Bitmap1Filename,$c16RGBPartialMatch);Find the full screen itself 1 seconds
; Be aware that overlapping windows, moving things on screen can make it difficult to find on full screen
findTester("SCREEN",$Bitmap2Filename,$c24RGBFullMatch);Find the full calculatorscreen
findTester("SCREEN",$Bitmap2Filename,$c24RGBPArtialMatch);Find the full calculatorscreen with partial match
findTester("SCREEN",$Bitmap2Filename,$c16RGBFullMatch);Find the full calculatorscreen
findTester("SCREEN",$Bitmap2Filename,$c16RGBPArtialMatch);Find the full calculatorscreen with partial match
findTester($Bitmap1Filename,$Bitmap2Filename,$c16RGBFullMatch);Find the full calculatorscreen
findTester($Bitmap1Filename,$Bitmap2Filename,$c16RGBPartialMatch);Find the full calculatorscreen with partial match
findTester($Bitmap2Filename,$Bitmap3Filename,$c24RGBFullMatch);Find the backspace button
findTester($Bitmap2Filename,$Bitmap3Filename,$c24RGBPartialMatch);Find the backspace button with partial match
findTester($Bitmap2Filename,$Bitmap3Filename,$c16RGBFullMatch);Find the backspace button
findTester($Bitmap2Filename,$Bitmap3Filename,$c16RGBPartialMatch);Find the backspace button with partial match
winactivate($calcHWND);Make sure calculator is active on the screen
findTester("[ACTIVE]",$Bitmap3Filename,$c24RGBFullMatch);Find the backspace button
findTester("[ACTIVE]",$Bitmap3Filename,$c24RGBPartialMatch);Find the backspace button with partial match
findTester("[ACTIVE]",$Bitmap3Filename,$c16RGBFullMatch);Find the backspace button on active screen
findTester("[ACTIVE]",$Bitmap3Filename,$c16RGBPartialMatch);Find the backspace button with partial match
findTester("SCREEN",$Bitmap3Filename,$c24RGBFullMatch);Find the backspace button
findTester("SCREEN",$Bitmap3Filename,$c24RGBPartialMatch);Find the backspace button with partial match
findTester("SCREEN",$Bitmap3Filename,$c16RGBFullMatch);Find the backspace button
findTester("SCREEN",$Bitmap3Filename,$c16RGBPartialMatch);Find the backspace button with partial match
findTester($Bitmap4Filename,$Bitmap5Filename,$c16RGBFullMatch);Find the seven
findTester($Bitmap4Filename,$Bitmap5Filename,$c16RGBPartialMatch);Find the seven with partial match
findTester($Bitmap4Filename,$Bitmap6Filename,$c16RGBFullMatch);Find the cat
findTester($Bitmap4Filename,$Bitmap6Filename,$c16RGBPartialMatch);Find the cat with partial match
findTester($Bitmap1Filename,$Bitmap7Filename,$c24RGBFullMatch);Find the 3 of Autoit Homepage
findTester($Bitmap1Filename,$Bitmap7Filename,$c24RGBPartialMatch);Find the 3 of Autoit Homepage
findTester($Bitmap1Filename,$Bitmap7Filename,$c16RGBFullMatch);Find the 3 of Autoit Homepage
findTester($Bitmap1Filename,$Bitmap7Filename,$c16RGBPartialMatch);Find the 3 of Autoit Homepage
_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 $fLine[1];Line number of found line(s), redimmed when second picture size is known
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=0;
dim $imgBytes;
local $iFuzzyDist, $searchFor, $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
ReDim $fline[$BMP2Height]
;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
$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)
;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)
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
[ 本帖最后由 autoita 于 2009-1-24 16:58 编辑 ] |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入
×
|