Сразу скажу - вопрос не об UDF PixelSearchEx. Искал максимально быстрый способ найти пиксель по цвету из памяти после того, как сделан скриншот. Нашел на англоязычном форуме такой же вопрос в 2012 году и весьма любопытный скрипт от Yashied в ответ. Навожу полный текст ответа: "If do not take into account the time for creating a screenshot, the _PixelSearchEx() is approximately 4 times faster than native PixelSearch(). To run this example you will need to download a WinAPIex UDF library."
Попробовал у себя. Закомментировал строки "$hBitmap = _WinAPI_CopyBitmap($hBitmap)" и "_WinAPI_DeleteObject($hBitmap)"- скорость выросла еще в 3-4 раза и уже стала такая же как в UDF FastFind в функции FFNearestPixel (2-3 мс у меня на картинке размером в экран 17 дюймов). Не знаю зачем здесь клонируется Bitmap и работа идет с клоном, может он как-то портится в ходе работы. Возможно можно вынести часть функции в основную программу, если я хочу много раз использовать функцию на одной и той же Bitmap. Очень хотелось бы иметь возможность находить не 1 пиксель за 1 вызов функции, а сразу столько, сколько надо.
Что и как сделать я не знаю просто потому, что не могу разобрать код. Споткнулся сразу на "__Init(Binary( _.......". Что это, откуда и зачем это? Догадываюсь, что это какой-то набор команд, как понять что там зашифровано... и что за __Init. Пожалуйста, помогите разобрать по винтикам функцию _PixelSearchEx(). Я думаю, что это пригодится не только мне, а еще очень многим.
Код:
#Include <ScreenCapture.au3>
#Include <WinAPIEx.au3>
$Timer = TimerInit()
$Pos = PixelSearch(0, 0, @DesktopWidth, @DesktopHeight, 0x00FFFF)
ConsoleWrite('PixelSearch() => X = ' & $Pos[0] & ', Y = ' & $Pos[1] & ', Time = ' & TimerDiff($Timer) & @CR & @CR)
$hBitmap = _ScreenCapture_Capture()
$Timer = TimerInit()
$Pos = _PixelSearchEx($hBitmap, 0x00FFFF)
ConsoleWrite('PixelSearchEx() => X = ' & $Pos[0] & ', Y = ' & $Pos[1] & ', Time = ' & TimerDiff($Timer) & @CR)
Func _PixelSearchEx($hBitmap, $iColor)
Static $pProc = 0
If Not $pProc Then
If @AutoItX64 Then
; Not implemented!
Return SetError(1, 0, 0)
Else
$pProc = __Init(Binary( _
'0x5553575631C0505050837C24280074118B6C2428837D14007407B801000000EB' & _
'0231C021C0747F8B6C24288B5D084B891C2431C03B04247F6DC7442404000000' & _
'008B6C24288B5D044B3B5C24047C528B6C24288B5D148B7C24048B34248B6C24' & _
'280FAF750401F7C1E70201FB895C24088B6C24088B5D0081E3FFFFFF003B5C24' & _
'2475188B5C24048B6C24288B7D082B3C244FC1E71009FB89D8EB14FF44240471' & _
'A0FF0C24718CB8FFFFFFFFEB0231C083C40C5E5F5B5DC21000'))
EndIf
EndIf
Local $tDIB, $tInt, $tPos, $aPos, $Ret, $Error = True
$hBitmap = _WinAPI_CopyBitmap($hBitmap)
If @error Then
Return SetError(1, 0, 0)
EndIf
Do
$tDIB = DllStructCreate($tagDIBSECTION)
If (Not _WinAPI_GetObject($hBitmap, DllStructGetSize($tDIB), DllStructGetPtr($tDIB))) Or (DllStructGetData($tDIB, 'bmBitsPixel') <> 32) Or (DllStructGetData($tDIB, 'biCompression')) Then
ExitLoop
EndIf
$Ret = _WinAPI_CallWindowProc($pProc, 0, $iColor, DllStructGetPtr($tDIB), 0)
If (@error) Or ($Ret = -1) Then
ExitLoop
EndIf
$Error = False
Until 1
_WinAPI_DeleteObject($hBitmap)
If $Error Then
Return SetError(1, 0, 0)
EndIf
$tInt = DllStructCreate('int')
$tPos = DllStructCreate('ushort;ushort', DllStructGetPtr($tInt))
DllStructSetData($tInt, 1, $Ret)
Dim $aPos[2]
For $i = 0 To 1
$aPos[$i] = DllStructGetData($tPos, $i + 1)
Next
Return $aPos
EndFunc ;==>_PixelSearchEx
Попробовал у себя. Закомментировал строки "$hBitmap = _WinAPI_CopyBitmap($hBitmap)" и "_WinAPI_DeleteObject($hBitmap)"- скорость выросла еще в 3-4 раза и уже стала такая же как в UDF FastFind в функции FFNearestPixel (2-3 мс у меня на картинке размером в экран 17 дюймов). Не знаю зачем здесь клонируется Bitmap и работа идет с клоном, может он как-то портится в ходе работы. Возможно можно вынести часть функции в основную программу, если я хочу много раз использовать функцию на одной и той же Bitmap. Очень хотелось бы иметь возможность находить не 1 пиксель за 1 вызов функции, а сразу столько, сколько надо.
Что и как сделать я не знаю просто потому, что не могу разобрать код. Споткнулся сразу на "__Init(Binary( _.......". Что это, откуда и зачем это? Догадываюсь, что это какой-то набор команд, как понять что там зашифровано... и что за __Init. Пожалуйста, помогите разобрать по винтикам функцию _PixelSearchEx(). Я думаю, что это пригодится не только мне, а еще очень многим.