1

Тема: AHK: Вариация при поиске пикселей

Всем доброго времени суток.
Есть скрипт:

#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
{
   A_Index_X := A_Index-1
   loop % height
   {
      CurrentPixel := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
      if (CurrentPixel = SearchPixel)
         n++
   }
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
msgbox % n

Он ищет количество пикселей в заданной области. Но ищет только определенный цвет.

Как сделать, чтоб скрипт искал не только один конкретный цвет, а и его оттенки с вариацией 10-20.

2 (изменено: serzh82saratov, 2017-08-23 19:24:42)

Re: AHK: Вариация при поиске пикселей

#include gdip.ahk
SetBatchLines, -1
CoordMode, Pixel, screen
pToken := Gdip_Startup()

SearchPixel := 0xFFB5E61D 
variation := 0x12 

pBitmap := Gdip_BitmapFromScreen("461|188|444|444")
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap)
MsgBox % width * height
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)
loop % width + (n:=0)
{
   A_Index_X := A_Index-1
   loop % height
   {
       CurrentPixel := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
      if CompareColors(SearchPixel, CurrentPixel, variation)
         n++
   }
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
msgbox % n

CompareColors(bgr1, bgr2, variation=0) {
	c1 := bgr1 & 0xff
	c2 := bgr2 & 0xff 
	if (abs(c1 - c2) > variation)
		return false
	c1 := (bgr1 >> 8) & 0xff
	c2 := (bgr2 >> 8) & 0xff
	if (abs(c1 - c2) > variation)
		return false
	c1 := (bgr1 >> 16) & 0xff
	c2 := (bgr2 >> 16) & 0xff
	if (abs(c1 - c2) > variation)
		return false
	return true
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

3

Re: AHK: Вариация при поиске пикселей

serzh82saratov Все прекрасно работает. Большое спасибо.

4

Re: AHK: Вариация при поиске пикселей

А не лучше ли не использовать функцию, а просто составить условие в цикле без присваивания каждый раз переменным уже известные значения.
Так как при разрешении монитора 1920x1080 каждое присваивание отнимает 0.3 секунды.

SetBatchLines, -1
a:=a_tickcount
loop % 1920*1080
   var := "z"
msgbox % a_tickcount - a

5 (изменено: serzh82saratov, 2017-08-23 22:07:15)

Re: AHK: Вариация при поиске пикселей

Ты про это:

SetBatchLines, -1
CoordMode, Pixel, screen
pToken := Gdip_Startup()

SearchPixel := 0xFFffffff
variation := 0x11

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)

Start := A_TickCount
loop % width + (n:=0)
{
   A_Index_X := A_Index-1
   loop % height
   { 
      if CompareColors(SearchPixel, Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride), variation)
         n++
   }
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
msgbox % n "`n" A_TickCount - Start

CompareColors(bgr1, bgr2, variation=0) { 
	if (abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
		return false 
	if (abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
		return false 
	if (abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
		return false
	return true
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

6

Re: AHK: Вариация при поиске пикселей

Про это:

SetBatchLines, -1
n:= 0, k:= 6
a:=a_tickcount
loop % 1920*1080
{
   if k = 6
      n++   
}
msgbox % n "`n" a_tickcount - a

SetBatchLines, -1
n:= 0, k:= 6
a:=a_tickcount
loop % 1920*1080
{
   if test(k)
      n++   
}
msgbox % n "`n" a_tickcount - a

test(var)
{
   if var = 6
      return true
}

7

Re: AHK: Вариация при поиске пикселей

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

8

Re: AHK: Вариация при поиске пикселей

Malcev Ну да, так лучше.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

9 (изменено: serzh82saratov, 2017-08-23 23:13:13)

Re: AHK: Вариация при поиске пикселей

Malcev В итоге такой код?

SetBatchLines, -1
CoordMode, Pixel, screen
pToken := Gdip_Startup()

SearchPixel := 0xFFffffff
variation := 0x11

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)

Start := A_TickCount
bgr1 := SearchPixel
loop % width + (n:=0)
{
	A_Index_X := A_Index-1
	loop % height
	{ 
		bgr2 := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
		if !(abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
		&& !(abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
		&& !(abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
			n++
	}
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken) 
msgbox % n "`n" A_TickCount - Start
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

10 (изменено: Vicoriyan, 2017-08-23 23:08:30)

Re: AHK: Вариация при поиске пикселей

serzh82saratov Что-то не так. Этот вариант скрипта оттенок 0xFFE6E61E от основного цвета 0xFFB9E61E уже считывает все пиксели при показателе вариации 0х1. Первый и второй вариант скрипта считывает оттенки при показателе вариации 0х30. Если поставить вариацию 0, то и показывает тоже 0.

11

Re: AHK: Вариация при поиске пикселей

Поправил.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

12

Re: AHK: Вариация при поиске пикселей

serzh82saratov Все работает.

13

Re: AHK: Вариация при поиске пикселей

serzh82saratov, да, так уже намного быстрее.

14

Re: AHK: Вариация при поиске пикселей

Появился такой вопрос. Можно сделать так, чтоб скрипт считывал картинку из файла, а не из скрина?

15

Re: AHK: Вариация при поиске пикселей

Gdip_CreateBitmapFromFile вместо Gdip_BitmapFromScreen.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16

Re: AHK: Вариация при поиске пикселей

Пожалуйста, подскажите, как задать клик по заданному цвету (или самому близкому к нему оттенку) в диапазоне координат экрана от x1230 y80 до x2040 y550?

17

Re: AHK: Вариация при поиске пикселей

serzh82saratov И далее в круглых скобках имя файла? Или его как-то по другому выносить нужно?

18 (изменено: serzh82saratov, 2017-08-24 23:22:49)

Re: AHK: Вариация при поиске пикселей

becauseim

SetBatchLines, -1
CoordMode, Pixel, screen
CoordMode, Mouse, screen
pToken := Gdip_Startup()

SearchPixel := 0xFFffffff
variation := 0x1

pBitmap := Gdip_BitmapFromScreen("1230|80|" 2040 - 1230 "|" 550 - 80)
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap) 
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)

Start := A_TickCount
bgr1 := SearchPixel
loop % width + (n:=0)
{
	A_Index_X := A_Index-1
	loop % height
	{ 
		bgr2 := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
		if !(abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
		&& !(abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
		&& !(abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
		{
			MouseClick, left, A_Index_X, A_Index-1 
			Break 2
		}
	}
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)  
Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

19

Re: AHK: Вариация при поиске пикселей

path = c:\fdfsdf.png
pBitmap := Gdip_CreateBitmapFromFile(path)
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20

Re: AHK: Вариация при поиске пикселей

serzh82saratov Вот попробовал еще так:

pBitmap := Gdip_CreateBitmapFromFile("payload.png")


Тоже вроде как работает. Расширение .jpg тоже работает.

21

Re: AHK: Вариация при поиске пикселей

Можно и так.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

22

Re: AHK: Вариация при поиске пикселей

Тогда вопрос чем-то похожий на вопрос от becauseim. Если у меня картинка 1200х900 и мне нужно в пределах этого расширения картинки назначить область сканирования 500х500?

23 (изменено: serzh82saratov, 2017-08-24 23:43:49)

Re: AHK: Вариация при поиске пикселей

Указывайте область здесь, вместо нулей х у.

Gdip_LockBits(pBitmap, 0, 0, 500, 500, Stride, Scan0, BitmapData)
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Вариация при поиске пикселей

serzh82saratov В принципе так и думал, но неуверенность взяла свое. Спасибо большое за разъяснение.

25 (изменено: Vicoriyan, 2017-08-25 19:32:42)

Re: AHK: Вариация при поиске пикселей

serzh82saratov Сегодня проверил и увидел, что не работает. Вставил координаты и назначил поле для сканирования и результата вообще никакого нет.

Gdip_LockBits(pBitmap, 210, 110, 500, 500, Stride, Scan0, BitmapData)

Ошибки тоже нет. Ставлю вместо 210, 110, нули и он мне показывает пиксели всей картинки.

26

Re: AHK: Вариация при поиске пикселей


width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap) 


width := 500
height := 500

Меняли?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

27

Re: AHK: Вариация при поиске пикселей

serzh82saratov Да.

28

Re: AHK: Вариация при поиске пикселей

А если мне нужно просканировать несколько участков на одной картинке, то сделать можно создав дополнительный цикл с другими координатами или можно как-то по короче сделать?

Я создал дополнительный цикл и он работает:

variation := 0x5
ArrayCount = 0
n1:=0
n2:=0
Loop, Read, potok-kod_2.ini
{
ArrayCount += 1
Array%ArrayCount% := A_LoopReadLine
}
Loop %ArrayCount%
{
SearchPixel := Array%A_Index%
SetBatchLines, -1
CoordMode, Pixel, screen
pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile("payload.jpg")
width := 500
height := 500
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)

bgr1 := SearchPixel
loop % width
{
A_Index_X := A_Index-1
loop % height
{ 
bgr2 := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
if !(abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
&& !(abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
&& !(abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
n1++
}
}

pBitmap := Gdip_CreateBitmapFromFile("payload.jpg")
width := 500
height := 500
Gdip_LockBits(pBitmap, 510, 0, width, height, Stride, Scan0, BitmapData)

bgr1 := SearchPixel
loop % width
{
A_Index_X := A_Index-1
loop % height
{ 
bgr2 := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
if !(abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
&& !(abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
&& !(abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
n2++
}
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
}
MsgBox, %n1% %n2%

29 (изменено: pixel75, 2022-12-05 23:22:31)

Re: AHK: Вариация при поиске пикселей

Простите великодушно господа, нет у меня в "битмапах" хоть сколько нибудь понимания, куда же всё таки вставлять верхнюю левую точку прямоугольника координат, в котором будут считаться пиксели искомого мною цвета?  То ли сюда:  Gdip_LockBits(pBitmap, 0, 0, 500, 500, Stride, Scan0, BitmapData) как указывал достопочтенный serzh82saratov, то ли сюда:  pBitmap := Gdip_BitmapFromScreen("1230|80|" 2040 - 1230 "|" 550 - 80), как было у автора поста.  Понятно, что фигурирует начальная точка и ширина и высота, но не понятно, почему курсор у меня тупо уезжает на координаты 0,0 в начало экрана в обоих случаях вместо того, чтобы кликнуть на ярлык красного цвета на рабочем столе. Тот случай, когда за годы накорябал сотни рабочих скриптов на AHK, а вот в этих "битмапах" - дуб дубом.
Тыкаюсь с вариантами сутки без сна, с головой, как трансформаторная будка и только злюсь. Помогите кто может, ткните как котенка мордой в лужу, что я делаю не так, просто скопировав код уважаемого serzh82saratov, вставляя свои координаты? Мне нужно в небольшом прямоугольнике координат сосчитать пиксели одного цвета ( хрен с ним, не уходя в дебри с оттенками) и исходя из количества найденных пикселей в области ( 30 например), совершить любое действие. И если можно, поясните пожалуйста, можно ли вместо цифр координат, запихнуть туда названия переменных их отражающих?

30

Re: AHK: Вариация при поиске пикселей

pixel75 пишет:

что я делаю не так, просто скопировав код уважаемого serzh82saratov

Если вы процитируете код, который используете, отвечающим не придётся его разыскивать, что повысит шанс на ответ.

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

31 (изменено: pixel75, 2022-12-06 08:37:49)

Re: AHK: Вариация при поиске пикселей

teadrinker, извините, видит Бог, старался придерживаться правила об избыточном цитировании. Да и переменной "n", отражавшей количество совпадений, в этой редакции, увы, нет. От себя добавил лишь горячую клавишу запуска. При запуске скрипта, либо ничего не происходит, ибо, вероятно цвет не найден, либо курсор уезжает на 0, 0 коодинаты. С Вашего позволения, напомню, что мне нужно в небольшом прямоугольнике координат сосчитать пиксели одного цвета, в идеале обозвав их количество Переменной_1, а количество близких по спектру Переменной_2, и исходя из количества найденных пикселей в области, ( 30 точных, 65 приблизительных, например), совершить любое действие. И если можно, поясните пожалуйста, можно ли вместо цифр координат, запихнуть названия переменных, отражающих координаты, с учетом того, что последние всякий новый Loop моего скрипта, будут меняться динамически?

; как сместить курсор на заданный или близкий по оттенку цвет, в диапазоне координат экрана от x79 y166  до x140 y230?
; tochka_x := 383
; tochka_y := 167
F6:: 	
SetBatchLines, -1
CoordMode, Pixel, screen
CoordMode, Mouse, screen
pToken := Gdip_Startup()

SearchPixel := 0x3641FC
variation := 0x1

pBitmap := Gdip_BitmapFromScreen("79|166|" 140 - 79 "|" 230 - 166)
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap) 
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)

Start := A_TickCount
bgr1 := SearchPixel
loop % width + (n:=0)
{
	A_Index_X := A_Index-1
	loop % height
	{ 
		bgr2 := Gdip_GetLockBitPixel(Scan0, A_Index_X, A_Index-1, Stride)
		if !(abs((bgr1 & 0xff) - (bgr2 & 0xff)) > variation)
		&& !(abs(((bgr1 >> 8) & 0xff) - ((bgr2 >> 8) & 0xff)) > variation)
		&& !(abs(((bgr1 >> 16) & 0xff) - ((bgr2 >> 16) & 0xff)) > variation)
		{
			MouseMove, A_Index_X, A_Index-1, 20 
			Break 2
		}
	}
}
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)  
Return

32

Re: AHK: Вариация при поиске пикселей

С виду всё правильно, только много лишних или неиспользуемых переменных: Start и n не используются, width и height не нужно получать заново, ведь ширина и высота уже есть, их нужно только присвоить переменным.

pixel75 пишет:

При запуске скрипта, либо ничего не происходит, ибо, вероятно цвет не найден, либо курсор уезжает на 0, 0 коодинаты

Если не происходит, значит не найдено, если уезжает, значит найдено в соответствующих координатах.

pixel75 пишет:

можно ли вместо цифр координат, запихнуть названия переменных, отражающих координаты

Можно, используя синтаксис выражений:

x := 0, y := 0, width := 140 - 79, height := 230 - 166
pBitmap := Gdip_BitmapFromScreen(x . "|" . y "|" . width . "|" . height)
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)

bgr1 := SearchPixel
loop % width
{
...
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33 (изменено: pixel75, 2022-12-06 18:32:22)

Re: AHK: Вариация при поиске пикселей

teadrinker в том то и горький катаклизм, дорогой Вы мой человек, что курсор уезжает в угол совершенно напрасно, ибо область поиска совсем не там, он уезжает просто на нулевую точку, вне зависимости от того, какие координаты я вписываю и какой цвет задаю, от того и вопрос, куда и как их, координаты, все таки вписывать по-православному. За ответ Вам в любом случае большое спасибо!Всё таки хотелось бы раскрыть и  тему того, как же все таки от отраженных в переменных пересчитанных пикселях, что либо предпринять?

34

Re: AHK: Вариация при поиске пикселей

А, вижу, что код не адаптирован под область поиска, начинающуюся не с 0, 0.
Замените

MouseMove, A_Index_X, A_Index-1, 20 

на

MouseMove, A_Index_X + x, A_Index-1 + y, 20 
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

35

Re: AHK: Вариация при поиске пикселей

teadrinker Колоссальное Вам спасибо, Учитель!