Тема: AHK: Захват любого изменения на экране
Необходимо делать определённое действие (клик пкм) при любом изменении на экране.
Подскажите пожалуйста, как это сделать, ибо нашёл только захват определённых пикселей или картинки.
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Необходимо делать определённое действие (клик пкм) при любом изменении на экране.
Подскажите пожалуйста, как это сделать, ибо нашёл только захват определённых пикселей или картинки.
Захватить картинку, и при изменении сделать действие.
А как бы ещё при этом получить координаты изменившихся пикселей?
Пиксели определяются координатами. Сравнивайте попиксельно — получите координаты.
Попиксельно чем? Если PixelGetColor, то даже при проверке каждого десятого пикселя проверка всего экрана занимает минуты. Можно что-то раз в 100 быстрее сделать с данными, которые помещаются в буфер при захвате картинки средствами Windows? Как их сравнить попиксельно?
У меня такого опыта не было, я бы попробовал через GetPixel.
Не смог разобраться с первым, второе вообще, как я понял про картинки.
Вот так попробовал:
cChk(MouseX, MouseY)
{
global ColorBGR
hdc := DllCall("GetDC", "uint", 0)
if hdc
{
ColorBGR := DllCall("GetPixel", "uint", hdc, "int", ceil(MouseX), "int", ceil(MouseY))
DllCall("ReleaseDC", "uint", 0, "uint", hdc)
Setformat, Integer, H
Return ColorBGR
}
}
1000 циклов - 14 секунд. Мне бы в 100-200 раз быстрее надо.
Неправильно поняли, вам подходит код из начала обсуждения, а про картинки там уже в конце.
Кроме того в вашем коде ошибка, вы не разобрались что делает ReleaseDC.
P.S.
FullHD пикселей за 2 секунды, в 100 раз быстрее чем вы хотите.
Что-то понял, что-то совсем нет. Вот такой у меня сейчас код:
SetBatchLines, -1
SetMouseDelay, -1
SetKeyDelay, -1
CoordMode, Pixel, screen
CoordMode, Mouse, screen
CoordMode,ToolTip, screen
pToken := Gdip_Startup()
SoundBeep
pBitmap := Gdip_BitmapFromScreen("0|0|1920|1080")
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap)
shag := 5
width_S := width / shag
height_S := height / shag
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)
Return
F3::
Start := A_TickCount
bgr1 := SearchPixel
loop % width_S
{
A_Index_X := A_Index * shag - 1
loop % height_S
{
A_Index_Y := A_Index * shag - 1
bgr2 := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index_Y, Stride)
if !(abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
&& !(abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
&& !(abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
Random,stop,1,5000
if (stop > 4999)
{
MouseMove,A_Index_X, A_index_Y
SetFormat,Integer,H
bgr2 := bgr2 + 0
ToolTip, A_LineNumber %A_index% %A_Index_X% %A_Index_Y% `n %bgr2%
SetFormat,Integer,D
Sleep, 2000
}
}
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
msgbox % A_LineNumber " " A_TickCount - Start
Return
Работает, но промахивается в координатах. Где-то координаты точки, где определяется цвет, расходятся с координатами, на которые указывает курсор на 10-20 единиц. Один раз из 3-4 выдаёт вообще что-то несусветное - цвета совершенно не соответствуют тому что на экране под курсором.
Где ошибка?
GDIP как-то иначе считает координаты? В чём отличие?
Почему у вас Gdip_BitmapFromScreen и метод lockbits находится в секции автовыполнения?
https://docs.microsoft.com/en-us/window … p-lockbits
Вот сюда ссылку давали: http://forum.script-coding.com/viewtopi … 86#p118686
Там тоже так:
#include gdip.ahk
n:=0, SearchPixel := 0xFFB5E61D
SetBatchLines, -1
CoordMode, Pixel, screen
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen("461|188|444|444")
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap)
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)
loop % width
Там поиск идет только один раз.
Кажется странности, прекратились, спасибо!
Я хочу сохранять и сравнивать результаты трёх сканирований экрана подряд. Как лучше это сделать? Двухмерные псевдомассивы типа Array_%x%_%y% при полях 1980 на 1080 заполняются и сравниваются очень долго.
Подскажите, пожалуйста, как ускорить процесс?
А вам надо узнать в каких координатах и какие цвета различаются?
Да, хочу поймать изменения на экране.
Научите хранить битмапы и читать из них координаты и цвет. Так наверное даже быстрее будет, если сохранить три битмапа, а потом только сравнивать их.
Ну, до первого упоминания здесь - это была часть заклинания графических духов. А теперь я думаю, что это такая хитрая переменная.
хочу поймать изменения на экране
Так вам надо поймать просто сам факт изменения, либо координаты в которых эти изменения произошли?
Да, список координат для анализа изменений. Их тоже может быть много - 10% от экрана это уже 200 000. Непонятно как их хранить.
Тогда пробуйте, как писал stealzy в 19 посте.
Как хранить зависит от того, как вы собираетесь их потом анализировать.
Я не понял как сохранять три переменных с содержимым этой переменной и как сравнивать их содержимое. Анализировать собираюсь для исключения мелких по площади изменений до 15х15 примерно, для поиска и выявления более крупных от 15х15 до 100х100, примерно. Пока такой подход планируется.
Не понимаю, что вы имеете в виду под
сохранять три переменных с содержимым этой переменной
Сохраняете 3 экрана под названиями:
loop 3
pBitmap%A_Index% := Gdip_BitmapFromScreen("0|0|1920|1080")
После чего блокируете изображения в памяти:
loop 3
Gdip_LockBits(pBitmap%A_Index%, 0, 0, 1920, 1080, Stride%A_Index%, Scan%A_Index%, BitmapData%A_Index%)
После чего пробегаетесь по пикселям и сравниваете.
А зачем блокировать?
Как пробежаться по пикселям сравнивая содержимое этих трёх переменных?
А зачем блокировать?
Я вам уже давал ссылку, там всё написано:
https://docs.microsoft.com/en-us/window … p-lockbits
Как пробежаться по пикселям сравнивая содержимое этих трёх переменных?
Вам нужно понять, что делает, например, этот код:
http://forum.script-coding.com/viewtopi … 86#p118686
Для этого надо посмотреть к каким функциям библиотеки Gdip он обращается, после чего уже посмотреть как эти функции устроены и какие вызовы dll они используют.
После чего почитать об этих вызовах на msdn.
Если же заниматься этим не хочется, то разместите ваше задание в коммерческий раздел.
Смотрел я всё это. Почти ничего не понял.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться