Что нового

Функция FastFind. Как реализовать аналог PixelSearch для участка экрана.

EVEGamer

Знающий
Сообщения
27
Репутация
12
Вопрос. Как с помощью FastFind, http://www.autoitscript.com/forum/topic/126430-advanced-pixel-search-library/ реализовать PixelSearch с шейдером для участка экрана.

Ответ.
Код:
#include <FastFind.au3>
;Local $aCoord = PixelSearch(0, 0, 100, 100, 0x576FA2,0x10); Ищем цвет значка автоит в углу окна SciTE
$aCoord = FFNearestSpot(1,1,1,1, 0x576FA2,0x10, True,0, 0, 100, 100)
If Not @error Then
   MouseMove($aCoord[0],$aCoord[1])
    MsgBox("", "", "X and Y are: " & $aCoord[0] & "," & $aCoord[1])
 EndIf


Розницу в скорости работы функций, в таком виде. Видно только в микроскоп.

Код:
#include <FastFind.au3>
$begin52 = TimerInit()
;FFSnapShot(0,0,100, 100)
For $c=0 to 9
;Local $aCoord = PixelGetColor (100, 100)
Local $aCoord = PixelSearch (0,0,100,100,0x355479,0x10)
;$aCoord = FFNearestSpot(1,1,1,1,0x355479,0x10,False)
;$aCoord = FFGetPixel(100, 100)
Next
ConsoleWrite(TimerDiff($begin52)&" - "&$aCoord[0]&":"&$aCoord[1]&@CRLF)


В таком виде, результат начинает радовать. Вывод, применение данной функции для единичных процессов, нецелесообразно. Скорость создания скриншота, примерно равна однократному вызову, базовой функции.
 

ivanius

Знающий
Сообщения
74
Репутация
5
Re: Функция FastFind. Как реализовать аналог PixelSearch для участка экрана

мною написан полностью соответствующий аналог стандартного PixelSearch + доп фитчи данной либы.
вот он:
Код:
Func _PixelSearch($Left, $Top, $Right, $Bottom, $Colors, $ShadeVariation = 0, $Step = 1, $hWnd = -1, $PixelsCount = 1, $AreaSize = 1, $PosX = -1, $PosY = -1)
	;calculate Real Pos and Size
	Local $Temp
	If $Left > $Right Then
		$Temp = $Right
		$Right = $Left
		$Left = $Temp
		$PosX = $Left
	EndIf
	If $Top > $Bottom Then
		$Temp = $Bottom
		$Bottom = $Top
		$Top = $Temp
		$PosY = $Bottom
	EndIf

	;check for Position
	If $PosX = -1 Then $PosX = $Right ;Int(($Right - $Left) / 2)
	If $PosY = -1 Then $PosY = $Top ;Int(($Bottom - $Top) / 2)
	If $PosX < 0 Then $PosX = 0
	If $PosY < 0 Then $PosY = 0
	;check for Colors
	If IsArray($Colors) Then
		FFResetColors()
		For $i = 0 To UBound($Colors) - 1
			FFAddColor($Colors[$i])
		Next
		$Colors = -1
	EndIf

	If $Left = 0 Then $Left = 1
	If $Top = 0 Then $Top = 1

	;FFNearestSpot($SizeSearch, $NbPixel, $PosX, $PosY, $Color, $ShadeVariation=0, $ForceNewSnap=true, $Left=0, $Top=0, $Right=0, $Bottom=0, $NoSnapShot=$FFLastSnap, $WindowHandle=-1)
	If $hWnd = -1 Then
		;FFAddExcludedArea()
		Local $result = FFNearestSpot($PixelsCount, $AreaSize, $PosX, $PosY, $Colors, $ShadeVariation, False, 0, 0, $Left + $Right, $Top + $Bottom, False, 0)
		;Local $result = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", $PixelsCount, "int*", $AreaSize, "int*", $PosX, "int*",$PosY, "int", $Colors, "int", $ShadeVariation, "int", $FFLastSnap)
	Else
		;FFAddExcludedArea($Left, $Top, $Right, $Bottom)
		Local $result = FFNearestSpot($PixelsCount, $AreaSize, $PosX, $PosY, $Colors, $ShadeVariation, False, $Left, $Top, $Right, $Bottom, False, $hWnd)
		;Local $result = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", $PixelsCount, "int*", $AreaSize, "int*", $PosX, "int*",$PosY, "int", $Colors, "int", $ShadeVariation, "int", $FFLastSnap)
		;FFResetExcludedAreas()
	EndIf
	;	ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $result = ' & $result & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
	;check for errors
	If Not IsArray($result) Then
		SetError(1)
		Return False
	Else
		Return $result
	EndIf

EndFunc   ;==>_PixelSearch

Но если честно хотелось бы большей скорости, а добиться ее можно только с помощью обращения напрямую к DLL, вот есть пример:
Код:
;из проверки скорости
 DllCall($FFDllHandle, "int", "FFGetPixel", "int", $x, "int", 500, "int", $FFLastSnap)
;из обертки (FastFind.au3)
Func FFNearestSpot($SizeSearch, $NbPixel, $PosX, $PosY, $Color, $ShadeVariation=0, $ForceNewSnap=true, $Left=0, $Top=0, $Right=0, $Bottom=0, $NoSnapShot=$FFLastSnap, $WindowHandle=-1)
	if Not SnapShotPreProcessor($Left, $Top, $Right, $Bottom, $ForceNewSnap, $NoSnapShot, $WindowHandle) Then
		SetError(2)
		Return False
	EndIf
	local $Result = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", $SizeSearch, "int*", $NbPixel, "int*", $PosX, "int*",$PosY, "int", $Color, "int", $ShadeVariation, "int", $NoSnapShot)
	If ((Not IsArray($Result)) OR $Result[0]<>1) Then
		SetError(1)
		Return False
	EndIF
	local $CoordResult[3] = [$Result[3], $Result[4], $Result[2]] ; PosX, PoxY, Nombre de pixels
	return $CoordResult
EndFunc
Func SnapShotPreProcessor($Left, $Top, $Right, $Bottom, $ForceNewSnap, $NoSnapShot, $WindowHandle)
	; Si on impose une nouvelle capture ou si aucun SnapShot valide n'a dйjа йtй effectuй pour ce N°
	if ($ForceNewSnap OR $FFLastSnapStatus[$NoSnapShot] <> 1) Then return FFSnapShot($Left, $Top, $Right, $Bottom, $NoSnapShot, $WindowHandle)
	Return True
EndFunc
Func FFSnapShot(const $Left=0, const $Top=0, const $Right=0, const $Bottom=0, const $NoSnapShot=$FFDefaultSnapShot, const $WindowHandle=-1)
	if ($WindowHandle <> -1) Then FFSetWnd($WindowHandle)
	$FFDefaultSnapShot = $NoSnapShot ; On mйmorise le no du SnapShot utilisй, cela restera le SnapShop par dйfaut pour les prochains appels
	local $Res = DllCall($FFDllHandle, "int", "SnapShot", "int", $Left, "int", $Top, "int", $Right, "int", $Bottom, "int", $NoSnapShot)
	If ( ((Not IsArray($Res)) AND ($Res=0)) OR $Res[0]=0) Then
		MsgBox(0, "FFSnapShot", "SnapShot ("&$Left&","&$Top&","&$Right&","&$Bottom&","&$NoSnapShot&","&Hex($WindowHandle,8)&") failed ")
		if (IsArray($Res)) Then
			MsgBox(0, "FFSnapShot Error", "IsArray($Res):"&IsArray($Res)&" - Ubound($Res):"&UBound($Res)&" - $Res[0]:"&$Res[0])
		else
			MsgBox(0, "FFSnapShot Error", "IsArray($Res):"&IsArray($Res)&" - $Res:"&$Res)
		EndIf
		$FFLastSnapStatus[$NoSnapShot] = -1
		SetError(2)
		Return False
	EndIf
	$FFLastSnapStatus[$NoSnapShot] = 1
	$FFLastSnap  = $NoSnapShot
	Return True
EndFunc

У меня не получается вызывать только чисто GenericColorSearch из DLL без первой половины - проверки SnapShot, при топ что я делаю его....
 
Верх