1 (изменено: Phoenixxx_Czar, 2021-06-01 17:42:49)

Тема: AHK: Поиск, обрезка на скриншоте

Добрейшего всем. Мне необходимо искать на экране картинку и если ее нашло - вырезать какую-то часть в найденной области.
Изначально я это сделал все через ImageSearch, если нашло, то делаем скриншот с найденными координатами + смещение.
Функция для скриншота была взята отсюда: http://forum.script-coding.com/viewtopi … 90#p121790.
Появилась проблема, что-то может произойти за эти доли миллисекунды или еще что-то и когда скриншот сделается, там уже что-то другое.

Я подумал как это можно сделать лучше, но как реализовать не знаю.
1. Мы делаем скиншот нужной нам области.
2. На этом скриншоте мы ищем то, что нам нужно.
3. Если мы нашли, то вырезаем нужным нам кусочек с этого скриншота.

Я попытался поискать на форуме, но ничего не нашел. Буду благодарен за помощь.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

2

Re: AHK: Поиск, обрезка на скриншоте

Phoenixxx_Czar пишет:

На этом скриншоте мы ищем то, что нам нужно

Ищите Gdip_ImageSearch().

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Поиск, обрезка на скриншоте

Я тут смотрел на функцию, которая скриншот делает в файл, дабы понять, как получить Bitmap, а не сохранение в файл, вроде понял.
Но возник вопрос, какой функцией можно вырезать нужный кусочек с этого Bitmap и сохранить в итоге в файл?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

4

Re: AHK: Поиск, обрезка на скриншоте

Обратите внимание на Gdip_DrawImage(), там можно указать координаты bitmap-источника.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Поиск, обрезка на скриншоте

Кхм.. Получилось что-то такое:

hBitmap := GetHBitmapFromScreen(0, 0, A_ScreenWidth, A_ScreenHeight)
gdip := new GDIplus
pBitmap := gdip.BitmapFromHBitmap(hBitmap)
DllCall("DeleteObject", Ptr, hBitmap)

newPBitmap := Gdip_CloneBitmapArea(pBitmap, 0, 0, 100, 100)

gdip.SaveBitmapToFile(newPBitmap, "test.png")
gdip.DisposeImage(pBitmap)
gdip.DisposeImage(newPBitmap)
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

6

Re: AHK: Поиск, обрезка на скриншоте

А, правильно, Gdip_CloneBitmapArea(), я и забыл про неё, нечасто с GDIplus приходится иметь дело. Только у вас какая-то путаница с классом GDIplus и библиотекой Gdip.ahk. Нужно что-то одно использовать, либо то, либо другое.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7 (изменено: Phoenixxx_Czar, 2021-06-02 03:52:24)

Re: AHK: Поиск, обрезка на скриншоте

1. Кхм.. Но в классе недостаточно функций, это получается нужно функции из библиотеки добавить в класс?
2. И еще такой вопрос, можно ли файл перенести как-то в код? То есть, файл который сейчас лежит в папке желательно убрать и хранить где-то в коде.
3. А так же, как из файла получить pBitmap (или hBitmap, я еще не понимаю в чем разница).

UPD: 3. Нашел - Gdip_CreateBitmapFromFile.
UPD: 1. Понял, функции из того класса есть в той библиотеки, просто названы по другому.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

8

Re: AHK: Поиск, обрезка на скриншоте

А вы открывайте библиотеку Gdip.ahk и смотрите по названиям функций, там должно быть понятно. Если хотите всё в одном скрипте, то да, переносите недостающие функции из Gdip.ahk в класс. hBitmap — это объект из GDI, pBitmap — из GDIplus. Если есть hBitmap, а нужно использовать GDIplus, то нужно преобразовать её в pBitmap соответствующей функцией.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Поиск, обрезка на скриншоте

Кхм.. А зачем используется GDI, а зачем GDI+? Я так понимаю для скриншота экрана использовано GDI (ибо мы hBitmap преобразовывали в pBitmap), почему именно GDI?
Где можно найти более удобное описание для функций? На гит хабе нет.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

10

Re: AHK: Поиск, обрезка на скриншоте

Описание всех функций есть на MSDN. GDI и GDIplus — это две разные технологии, GDI — более старая, GDIplus — более продвинутая. Для скриншота можно использовать вариант с GDI, если не нужно сохранять его в файл в форматах, отличных от BMP, чтобы не тащить в скрипт более громоздкую библиотеку для GDIplus. Но если она всё равно используется, например через #Include, то там уже есть соответствующая функция для получения Bitmap с экрана.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Поиск, обрезка на скриншоте

Можете объяснить, за что отвечает "Raster"?

; Function				Gdip_BitmapFromScreen
; Description			Gets a gdi+ bitmap from the screen
;
; Screen				0 = All screens
;						Any numerical value = Just that screen
;						x|y|w|h = Take specific coordinates with a width and height
; Raster				raster operation code
;
; return      			If the function succeeds, the return value is a pointer to a gdi+ bitmap
;						-1:		one or more of x,y,w,h not passed properly
;
; notes					If no raster operation is specified, then SRCCOPY is used to the returned bitmap

Gdip_BitmapFromScreen(Screen=0, Raster="")
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

12

Re: AHK: Поиск, обрезка на скриншоте

https://docs.microsoft.com/en-us/window … gdi-bitblt
Последний параметр.

13

Re: AHK: Поиск, обрезка на скриншоте

Вы имели опыт с Gdip_ImageSearch? Насколько он быстрый по сравнению с ImageSearch?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

14

Re: AHK: Поиск, обрезка на скриншоте

Собственно, в Gdip_BitmapFromScreen() он не нужен, непонятно, зачем используется.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

15

Re: AHK: Поиск, обрезка на скриншоте

Почему не нужно?
Я помню, что иногда нужно было CAPTUREBLT указывать.

16

Re: AHK: Поиск, обрезка на скриншоте

Phoenixxx_Czar пишет:

Вы имели опыт с Gdip_ImageSearch?

Да, он медленней. Хоть и написан на машинном коде.
Алгоритм поиска картинок на атохотки - банальное сравнивание всех пикселей с 2 источников.

17

Re: AHK: Поиск, обрезка на скриншоте

Malcev пишет:

иногда нужно было CAPTUREBLT указывать

Да? Мне вроде не приходилось. А зачем это было нужно?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

18

Re: AHK: Поиск, обрезка на скриншоте

Не помню уже.
Но на семерке какие-то окна не захватывались, то ли хардверно ускоренные, то ли полупрозрачные.
Что-то, помню с wmp у меня связано было.
Завтра могу проверить.

19

Re: AHK: Поиск, обрезка на скриншоте

А, что-то такое припоминаю. Посмотри, будет полезно вспомнить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

20 (изменено: Phoenixxx_Czar, 2021-06-02 06:03:14)

Re: AHK: Поиск, обрезка на скриншоте

Malcev пишет:

Да, он медленней. Хоть и написан на машинном коде.

Кхм.. Ну на удивление заняло 31мс. Первый поиск был в области 0, 200, 1920, 400 (картинка 110*110). Второй уже в найденной прошлой, в области 0, 0, 70, 90 (перебирало 2 картинки 70*90). Интересно что получится в маштабе. Это уже проверять буду позже.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

21 (изменено: Phoenixxx_Czar, 2021-06-02 15:35:37)

Re: AHK: Поиск, обрезка на скриншоте

Если я при запуске скрипта создаю Битмап из файла (Gdip_CreateBitmapFromFile), мне его нужно уничтожать (Gdip_DisposeImage) перед выключением (Gdip_Shutdown)?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

22

Re: AHK: Поиск, обрезка на скриншоте

Нужно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

23

Re: AHK: Поиск, обрезка на скриншоте

Malcev пишет:

Не помню уже.
Но на семерке какие-то окна не захватывались, то ли хардверно ускоренные, то ли полупрозрачные.
Что-то, помню с wmp у меня связано было.

У меня WMP на WinXP обычным скриншотом не захватывался (чёрный квадрат получается вместо картинки), а в Win7 нормально захватывает.

24

Re: AHK: Поиск, обрезка на скриншоте

Проверил.
На семерке без CAPTUREBLT не захватывается панель с кнонопками play pause в wmp.
И еще не захватываются тултипы.

25

Re: AHK: Поиск, обрезка на скриншоте

Phoenixxx_Czar пишет:

2. И еще такой вопрос, можно ли файл перенести как-то в код?

Можно сохранять в свой скрипт в виде HEX / Base64 строки, затем обратно в файл записывать, либо сразу в память загружать из строки.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

26

Re: AHK: Поиск, обрезка на скриншоте

Я сначала не понял, про какой файл идёт речь, думал, что про библиотеку. Если файл изображения — то можно его сохранить в base64 и записать в код в виде строки.

Malcev пишет:

Проверил.

Ага, спасибо. У меня есть свой скрипт для скриншотов, проверил — вроде всё захватывает, потом посмотрел, что там как раз CAPTUREBLT используется.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Поиск, обрезка на скриншоте

__Михаил__ пишет:
Phoenixxx_Czar пишет:

2. И еще такой вопрос, можно ли файл перенести как-то в код?

Можно сохранять в свой скрипт в виде HEX / Base64 строки, затем обратно в файл записывать, либо сразу в память загружать из строки.

Какой метод короче выйдет?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

28

Re: AHK: Поиск, обрезка на скриншоте

С извлечением из скрипта - меньше проблем. Для новичков в самый раз думаю.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

29

Re: AHK: Поиск, обрезка на скриншоте

__Михаил__ пишет:

С извлечением из скрипта - меньше проблем.

Имеете ввиду FileInstall?

Я сейчас перевел картинку в base64, не нашел метода с hex. Вроде не так много места занимает строка.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

30

Re: AHK: Поиск, обрезка на скриншоте

hex будет больше места занимать.