AutoIt: 3.3.8 +
Категория: Графика, GDI+, Строки
Описание: Функция _PicInPic() предназначена для поиска картинки в картинке (Picture In Picture).
Данная функция появилась в результате экспериментов по поиску бинарных данных в текстовом виде. Сразу хочу заметить, что если нужен мгновенный поиск на большой картинке или необходимо найти несколько одинаковых картинок сразу, то нужно использовать BmpSearch UDF.
Параметрами функции являются две картинки: первая - на которой искать, вторая - которую искать. В качестве любой из картинок может быть либо объект gdi32 (скриншот), либо объект GDI+ (картинка из файла), либо просто путь к файлу с картинкой. В случае успешного поиска функция возвращает массив координат левого верхнего угла искомой картинки относительно левого верхнего угла картинки, на которой производился поиск. В @extended записывается время поиска в миллисекундах. При проблемах, а также при неудачном поиске, устанавливается @error. @error = 1 означает, что картинка не найдена. Остальные ошибки указаны в описании функции.
Обращаю внимание:
- функция требует подключения #include <GDIPlus.au3> или #include <ScreenCapture.au3>
- для обеспечения успешного поиска картинку нужно сохранять в форматах без потерь: BMP или PNG
- при самостоятельном создании объектов, во избежание утечек памяти, не забывайте их удалять после работы функции, когда объекты больше не нужны
Код:
Примеры:
Тестирование производительности:
Источник: autoit-script.ru
Автор: InnI
Категория: Графика, GDI+, Строки
Описание: Функция _PicInPic() предназначена для поиска картинки в картинке (Picture In Picture).
Данная функция появилась в результате экспериментов по поиску бинарных данных в текстовом виде. Сразу хочу заметить, что если нужен мгновенный поиск на большой картинке или необходимо найти несколько одинаковых картинок сразу, то нужно использовать BmpSearch UDF.
Параметрами функции являются две картинки: первая - на которой искать, вторая - которую искать. В качестве любой из картинок может быть либо объект gdi32 (скриншот), либо объект GDI+ (картинка из файла), либо просто путь к файлу с картинкой. В случае успешного поиска функция возвращает массив координат левого верхнего угла искомой картинки относительно левого верхнего угла картинки, на которой производился поиск. В @extended записывается время поиска в миллисекундах. При проблемах, а также при неудачном поиске, устанавливается @error. @error = 1 означает, что картинка не найдена. Остальные ошибки указаны в описании функции.
Обращаю внимание:
- функция требует подключения #include <GDIPlus.au3> или #include <ScreenCapture.au3>
- для обеспечения успешного поиска картинку нужно сохранять в форматах без потерь: BMP или PNG
- при самостоятельном создании объектов, во избежание утечек памяти, не забывайте их удалять после работы функции, когда объекты больше не нужны
Код:
Код:
; ==============================================================================================================
; Имя функции : _PicInPic
; Описание : Поиск картинки в картинке
; Синтаксис : _PicInPic($vPic1, $vPic2)
; Параметры : $vPic1 - картинка, в которой производится поиск (объект GDI+ или объект gdi32 или путь к файлу)
; : $vPic2 - картинка, которую необходимо найти (объект GDI+ или объект gdi32 или путь к файлу)
; Возвращает : Успех - массив координат левого верхнего угла искомой картинки
; : относительно картинки, в которой производится поиск
; : $aArray[0] - X координата
; : $aArray[1] - Y координата
; : @extended - время поиска в миллисекундах
; : Неудача - 0 и устанавливает @error
; : @error = 1 - картинка не найдена
; : @error = 2 - файл $vPic1 не найден
; : @error = 3 - файл $vPic2 не найден
; : @error = 4 - ошибка определения размера $vPic1
; : @error = 5 - ошибка определения размера $vPic2
; : @error = 6 - картинка $vPic1 меньше картинки $vPic2
; Автор : InnI
; Примечание : Необходимо подключение #include <GDIPlus.au3> или #include <ScreenCapture.au3>
; ==============================================================================================================
Func _PicInPic($vPic1, $vPic2)
Local $fDel1, $fDel2, $hImg1, $hImg2, $iTime = TimerInit()
_GDIPlus_Startup()
If IsString($vPic1) Then
If Not FileExists($vPic1) Then Return SetError(2, _GDIPlus_Shutdown(), 0)
$vPic1 = _GDIPlus_BitmapCreateFromFile($vPic1)
$fDel1 = 1
Else
$hImg1 = _GDIPlus_BitmapCreateFromHBITMAP($vPic1)
If Not @error Then
$vPic1 = $hImg1
$fDel1 = 1
EndIf
EndIf
If IsString($vPic2) Then
If Not FileExists($vPic2) Then Return SetError(3, _GDIPlus_Shutdown(), 0)
$vPic2 = _GDIPlus_BitmapCreateFromFile($vPic2)
$fDel2 = 1
Else
$hImg2 = _GDIPlus_BitmapCreateFromHBITMAP($vPic2)
If Not @error Then
$vPic2 = $hImg2
$fDel2 = 1
EndIf
EndIf
Local $iW1 = _GDIPlus_ImageGetWidth($vPic1)
If @error Then Return SetError(4, _GDIPlus_Shutdown(), 0)
Local $iW2 = _GDIPlus_ImageGetWidth($vPic2)
If @error Then Return SetError(5, _GDIPlus_Shutdown(), 0)
Local $iH1 = _GDIPlus_ImageGetHeight($vPic1)
Local $iH2 = _GDIPlus_ImageGetHeight($vPic2)
If $iW1 < $iW2 Or $iH1 < $iH2 Then
If $fDel1 Then _GDIPlus_BitmapDispose($vPic1)
If $fDel2 Then _GDIPlus_BitmapDispose($vPic2)
Return SetError(6, _GDIPlus_Shutdown(), 0)
EndIf
Local $tBits1 = _GDIPlus_BitmapLockBits($vPic1, 0, 0, $iW1, $iH1, $GDIP_ILMREAD, $GDIP_PXF24RGB)
Local $iDiff1 = Abs(DllStructGetData($tBits1, "Stride")) - $iW1 * 3
Local $sText1 = StringTrimLeft(DllStructGetData(DllStructCreate("byte[" & ($iW1 * 3 + $iDiff1) * $iH1 & "]", DllStructGetData($tBits1, "Scan0")), 1), 2)
Local $aLines1[$iH1], $c = 0, $iLen = $iW1 * 6, $iStep = $iLen + $iDiff1 * 2
For $i = 1 To StringLen($sText1) Step $iStep
$aLines1[$c] = StringMid($sText1, $i, $iLen)
$c += 1
Next
_GDIPlus_BitmapUnlockBits($vPic1, $tBits1)
Local $tBits2 = _GDIPlus_BitmapLockBits($vPic2, 0, 0, $iW2, $iH2, $GDIP_ILMREAD, $GDIP_PXF24RGB)
Local $iDiff2 = Abs(DllStructGetData($tBits2, "Stride")) - $iW2 * 3
Local $sText2 = StringTrimLeft(DllStructGetData(DllStructCreate("byte[" & ($iW2 * 3 + $iDiff2) * $iH2 & "]", DllStructGetData($tBits2, "Scan0")), 1), 2)
Local $aLines2[$iH2], $c = 0, $iLen = $iW2 * 6, $iStep = $iLen + $iDiff2 * 2
For $i = 1 To StringLen($sText2) Step $iStep
$aLines2[$c] = StringMid($sText2, $i, $iLen)
$c += 1
Next
_GDIPlus_BitmapUnlockBits($vPic2, $tBits2)
Local $iMid = Floor($iH2 / 2), $iLen1 = StringLen($aLines1[0]), $iLen2 = StringLen($aLines2[0]), $iPos, $iStart, $iLine, $aXY[2]
For $i1 = $iMid To $iH1 - 1
$iStart = 1
While $iStart <= $iLen1
$iPos = StringInStr($aLines1[$i1], $aLines2[$iMid], 1, 1, $iStart)
If $iPos Then
If Mod($iPos - 1, 6) Then
$iStart = $iPos + 2
ContinueLoop
EndIf
If $i1 + $iH2 - $iMid > $iH1 Then Return SetError(1, _GDIPlus_Shutdown(), 0)
$iLine = $i1 - $iMid
For $i2 = 0 To $iH2 - 1
If StringMid($aLines1[$iLine], $iPos, $iLen2) == $aLines2[$i2] Then
$iLine += 1
Else
ExitLoop
EndIf
Next
If $i2 = $iH2 Then
$aXY[0] = ($iPos - 1) / 6
$aXY[1] = $i1 - $iMid
If $fDel1 Then _GDIPlus_BitmapDispose($vPic1)
If $fDel2 Then _GDIPlus_BitmapDispose($vPic2)
_GDIPlus_Shutdown()
Return SetError(0, TimerDiff($iTime), $aXY)
Else
$iStart = $iPos + 6
EndIf
Else
ExitLoop
EndIf
WEnd
Next
If $fDel1 Then _GDIPlus_BitmapDispose($vPic1)
If $fDel2 Then _GDIPlus_BitmapDispose($vPic2)
Return SetError(1, _GDIPlus_Shutdown(), 0)
EndFunc ;==>_PicInPic
Примеры:
Код:
; Пример поиска картинки на всём экране
; картинка находится в файле в папке скрипта
#include <ScreenCapture.au3>
$hBmp = _ScreenCapture_Capture()
$aCoord = _PicInPic($hBmp, "pic.png")
If @error Then
MsgBox(0, "Error", "Ошибка: " & @error)
Else
MsgBox(0, "Координаты", "X = " & $aCoord[0] & @CRLF & _
"Y = " & $aCoord[1] & @CRLF & _
"Время: " & @extended & "мс")
EndIf
_WinAPI_DeleteObject($hBmp)
Код:
; Пример отслеживания перемещения картинки,
; загруженной из файла, по всему экрану
; с выводом координат в консоль SciTE
#include <ScreenCapture.au3>
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile("pic.png")
Global $X = -1, $Y = -1
While Sleep(11)
$hBmp = _ScreenCapture_Capture()
$aXY = _PicInPic($hBmp, $hImage)
If Not @error Then
If $aXY[0] <> $X Or $aXY[1] <> $Y Then
ConsoleWrite($aXY[0] & ":" & $aXY[1] & @CRLF)
$X = $aXY[0]
$Y = $aXY[1]
EndIf
EndIf
_WinAPI_DeleteObject($hBmp)
WEnd
Тестирование производительности:
Тестовое окружение: Core i5 3.20 GHz, Windows 7, AutoIt 3.3.14.2
- поиск FullHD скриншота на самом скриншоте -> 150мс
- поиск иконки в трее на FullHD скриншоте -> 110мс
- поиск кнопки "Изменение цветов" в панели Paint -> 12мс
- поиск правого нижнего пикселя в квадрате 100х100 -> 1мс
- поиск FullHD скриншота на самом скриншоте -> 150мс
- поиск иконки в трее на FullHD скриншоте -> 110мс
- поиск кнопки "Изменение цветов" в панели Paint -> 12мс
- поиск правого нижнего пикселя в квадрате 100х100 -> 1мс
Источник: autoit-script.ru
Автор: InnI