请问窗口截图后再找图 能不能不经过生成文件
搜索了一个下午 找到一个前辈写的代码感觉非常高效 速度快 加上要生成图片文件的时间 都只需要1秒钟的样子 还是纯AU3因为搜得太多 所以不记得是哪位前辈了 总之要感谢你代码先要读取Source.Bmp文件 所以我在前面加了一句 截图 已经能够达到想要的效果了 但是运行的时候会生成一个Source.Bmp可不可以直接读截到的图 不生成文件
截到的图生成文件又从文件中取出来降低了效率
_ScreenCapture_CaptureWnd (@DesktopDir&"\Source.Bmp", $hwnd)
$hBitmap1 = _GDIPlus_BitmapCreateFromFile($s_dir & "\Source.Bmp")
$array1 = _myReadBitmapMsg($hBitmap1, 1)
当我改成这样时运行后没反映没多久脚本就没反映 关闭了
$hBitmap1 = _ScreenCapture_CaptureWnd ("", $hwnd)
$array1 = _myReadBitmapMsg($hBitmap1, 1)
全部代码
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
;#include <myOcrFunc.au3>
_GDIPlus_Startup ()
$s_dir = @DesktopDir
$hwnd = WinGetHandle ("纸牌")
_ScreenCapture_CaptureWnd (@DesktopDir&"\Source.Bmp", $hwnd)
$hBitmap1 = _GDIPlus_BitmapCreateFromFile($s_dir & "\Source.Bmp")
$array1 = _myReadBitmapMsg($hBitmap1, 1)
$hBitmap2 = _GDIPlus_BitmapCreateFromFile($s_dir & "\Search.Bmp")
$array2 = _myReadBitmapMsg($hBitmap2, 1)
$iMax = _GDIPlus_ImageGetWidth ($hBitmap1) / _GDIPlus_ImageGetWidth ($hBitmap2)
$t=TimerInit()
$aPosMsg = _ArrayComp($array1, $array2, False, $iMax)
ConsoleWrite("找到一个图片块用去时间:"&TimerDiff($t)&'毫秒,位置信息(为空未找到):'&$aPosMsg&@CRLF)
$t=TimerInit()
$aPosMsg = _ArrayComp($array1, $array2, True, $iMax)
ConsoleWrite("找到所有图片块用去时间:"&TimerDiff($t)&'毫秒,位置信息(为空未找到):'&$aPosMsg&@CRLF)
If $aPosMsg<>"" Then
Local $aPos, $i, $hGraphics = _GDIPlus_ImageGetGraphicsContext ($hBitmap1)
$aPosMsg = StringSplit($aPosMsg,"|",2)
For $i = 0 To UBound($aPosMsg)-1
$aPos = StringSplit($aPosMsg[$i],",",2)
_GDIPlus_GraphicsDrawRect($hGraphics, $aPos, $aPos, $aPos, $aPos)
Next
_GDIPlus_ImageSaveToFile($hBitmap1, $s_dir&"\Target.bmp")
_GDIPlus_GraphicsDispose ($hGraphics)
EndIf
_GDIPlus_ImageDispose ($hBitmap1)
_WinAPI_DeleteObject ($hBitmap1)
_GDIPlus_ImageDispose ($hBitmap2)
_WinAPI_DeleteObject ($hBitmap2)
_GDIPlus_ShutDown ()
Exit
;一般来说,当$hBitmap2是小图时$iType=1, 较大时$iType=0, 如果已知$array2哪个元素进行搜索比较合理,直接指定为$iY
Func _ArrayComp($array1, $array2, $SearchAll=False, $iMax=0, $iY=0, $iType=0)
Local $iExtended=0
If $iMax>0 And $iY=0 Then
Local $t=TimerInit()
Local $sBmpData1 = ""
For $i = 0 To UBound($array1)-1;相当于_ArrayToString或_myReadBitmapMsg($hBitmap,0),但更快
$sBmpData1 &= $array1[$i]
Next;===>当多个$array2搜索时,这个内容考虑在udf外执行,_ArrayComp($sBmpData1, $array1, $array2, $SearchAll=False, $iMax=0, $iY=0, $iType=0)
For $i = 0 To UBound($array2)-1
If StringReplace($array2[$i], StringLeft($array2[$i],6),"")="" Then ContinueLoop
Select
Case $iType = 0
$iY = $i
ExitLoop
#cs
Case $iType = 1 And Not @AutoItX64 ;pusofalse提供的多线程方法
;该方法中映射文件到内容部分 $pBaseAddress 暂用本段代替
Local $tBuff = DllStructCreate("char ["&StringLen($sBmpData1)+1&"]")
DllStructSetData($tBuff, 1, $sBmpData1)
$pBaseAddress = DllStructGetPtr($tBuff)
;http://www.autoitx.com/thread-20592-1-3.html
#ce
Case Else
StringReplace($sBmpData1,$array2[$i],"",0, 1)
If $iExtended=0 Or $iExtended>@extended Then
$iExtended=@extended
If $iExtended=0 Then Return "";没有匹配的图块
$iY = $i
If $iExtended<=$iMax Then ExitLoop
EndIf
EndSelect
Next
ConsoleWrite("获取最佳搜索串"&TimerDiff($t)&','&$iExtended&@CRLF)
EndIf
;Local $t=TimerInit()
If UBound($array1)<UBound($array2) Then Return ""
Local $s_re="", $y, $y2, $iW2=StringLen($array2[$iY]), $iPos;, $iSearchPos
For $y = $iy To UBound($array1)-1
$iPos = 0;$iSearchPos = 1
While $y+UBound($array2)<=UBound($array1)
$iPos = StringInStr($array1[$y], $array2[$iY], 1, 1, $iPos+1);$iPos = StringInStr($array1[$y], $array2[$iY], 1, 1, $iSearchPos)
Select
Case $iPos = 0
ContinueLoop(2)
Case Mod($iPos-1,6)<>0 ;Or $y<$iy
;$iSearchPos = $iPos+1
ContinueLoop
EndSelect
For $y2 = $iY To UBound($array2)-1
If StringMid($array1[$y+$y2-$iy], $iPos, $iW2)<>$array2[$y2] Then
;$iSearchPos = $iPos+1
ContinueLoop(2)
EndIf
Next
For $y2 = 0 To $iY-1
If StringMid($array1[$y+$y2-$iy], $iPos, $iW2)<>$array2[$y2] Then
;$iSearchPos = $iPos+1
ContinueLoop(2)
EndIf
Next
$s_re &= ($iPos-1)/6&','&$y-$iy&','&$iW2/6&','&UBound($array2)&"|"
StringReplace($s_re,"|","")
If (Not $SearchAll) Or ($iExtended>0 And @extended>=$iExtended) Then ExitLoop(2)
;$iSearchPos = $iPos+1
WEnd
Next
If StringRight($s_re,1)="|" Then $s_re = StringTrimRight($s_re,1)
;ConsoleWrite(TimerDiff($t)&@CRLF);18
Return $s_re
EndFunc
Func _myReadBitmapMsg($hBitmap, $iType=1);
Local $aBmpData
$aBmpData = _GDIPlus_ImageGetWidth ($hBitmap)
$aBmpData = _GDIPlus_ImageGetHeight ($hBitmap)
Local $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $aBmpData, $aBmpData, $GDIP_ILMREAD, $GDIP_PXF24RGB)
$aBmpData = Abs(DllStructGetData($BitmapData, "Stride"))
$aBmpData = DllStructGetData($BitmapData, "Scan0");
_GDIPlus_BitmapUnlockBits($hBitmap, $BitmapData)
Local $tBuff, $iH
Switch $iType;已测试比StringRegExp快
Case -1
Return $aBmpData
Case 0
For $iH = 1 To $aBmpData
$tBuff = DllStructCreate("byte[" & ($aBmpData*3) & "]", $aBmpData + ($iH-1)*$aBmpData)
$aBmpData &= StringTrimLeft(DllStructGetData($tBuff, 1),2)
Next
Return $aBmpData
Case Else
Local $aRet[$aBmpData]
For $iH = 1 To $aBmpData
$tBuff = DllStructCreate("byte[" & ($aBmpData*3) & "]", $aBmpData + ($iH-1)*$aBmpData)
$aRet[$iH-1] = StringTrimLeft(DllStructGetData($tBuff, 1), 2)
Next
Return $aRet
EndSwitch
EndFunc
好高深,都不看懂 回复 1# zch11230
要区分好位图句柄和位图对象句柄的区别:
$hBMP = _ScreenCapture_CaptureWnd ("", $hwnd)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
$array1 = _myReadBitmapMsg($hImage, 1)
回复 3# happytc
能帮我实测一下吗?我照这样式改了也还是不行 因为$hBitmap1在后面好像有调用 所以变量名没敢改 把前面的变动了一下 回复 4# zch11230
我机子里没有纸牌游戏,也没有看这个代码后面是干啥的,好象还载入了Search.bmp文件。
也不知道这一堆代码是干啥用的,懒得看了,只是看了你第一个框框里三行代码帮你写的那几行了 再最后顶一下如果没有答案就将就现在的方法了 不生成文件可能也行,不过你这套东西基本就用不上了 不生成文件可能也行,不过你这套东西基本就用不上了
netegg 发表于 2011-10-27 02:55 http://www.autoitx.com/images/common/back.gif
同感,不过我也没找到不生成文件的方法 生成二进制行不 生成二进制行不
menfan 发表于 2011-10-27 10:25 http://www.autoitx.com/images/common/back.gif
貌似只能只能这么干,直接处理内存数据 顶一下楼主,截个图成文件,还得再复制,麻烦,希望能有更好用的工具,谢谢大家。
页:
[1]