Is there any way to search for multiple pixels for multiple color??

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
killmatt01
Posts: 20
Joined: 25 Mar 2021, 00:12
Contact:

Is there any way to search for multiple pixels for multiple color??

Post by killmatt01 » 27 Apr 2021, 17:52

Well i don't mean color range
I have a list of color which contains 0xFF0000, 0x00FF00, 0x00FFFF, 0x1949EE... totally 100+ different colors.
Is it possible to check if certain area of my screen (160*90 pixel) contains ANY one of those colors?
I understand i can check one by one but it is TOO SLOW. Pixelsearch and pixelgetcolor both need averagely 7 ms for each run on my laptop, and i need the new method take less 20ms for each run. Is it possible?
User avatar
boiler
Posts: 17392
Joined: 21 Dec 2014, 02:44

Re: Is there any way to search for multiple pixels for multiple color??

Post by boiler » 27 Apr 2021, 18:33

killmatt01 wrote: Pixelsearch and pixelgetcolor both need averagely 7 ms for each run on my laptop, and i need the new method take less 20ms for each run. Is it possible?
I guess there's a typo above. You say it averages 7 ms but you need it to take less than 20 ms.

You could use LockBits and write some code in C and compile it to machine code to compare the memory locations directly to each of the elements in the array of colors. I don't know if would be fast enough, but it would be much faster than using PixelSearch or PixelGetColor.

There are various examples of using the above techniques. Here is one I did recently: Gidp_ExpandColor
killmatt01
Posts: 20
Joined: 25 Mar 2021, 00:12
Contact:

Re: Is there any way to search for multiple pixels for multiple color??

Post by killmatt01 » 27 Apr 2021, 20:00

boiler wrote:
27 Apr 2021, 18:33
killmatt01 wrote: Pixelsearch and pixelgetcolor both need averagely 7 ms for each run on my laptop, and i need the new method take less 20ms for each run. Is it possible?
I guess there's a typo above. You say it averages 7 ms but you need it to take less than 20 ms.

You could use LockBits and write some code in C and compile it to machine code to compare the memory locations directly to each of the elements in the array of colors. I don't know if would be fast enough, but it would be much faster than using PixelSearch or PixelGetColor.

There are various examples of using the above techniques. Here is one I did recently: Gidp_ExpandColor
Thank you for help!
I am sorry for not explaining it correctly, I mean if one color at a time, pixelsearch and pixelgetcolor would take 7 ms each, when i need more colors each time it will definitely take longer. Yeah i was thinking how to write this method (compare the memory locations directly to each of the elements in the array of colors) in just ahk since it's a pure ahk practicing project.
Thx again!
User avatar
boiler
Posts: 17392
Joined: 21 Dec 2014, 02:44

Re: Is there any way to search for multiple pixels for multiple color??

Post by boiler » 27 Apr 2021, 21:25

You can write the code in AHK for the comparison in memory using Gdip_LockBits as shown in my example that uses MCode and it would still be faster than using the PixelSearch or PixelGetColor methods. The LockBits gives you the memory location of the start of the data, and then you just compare byte values with those in your array. For that many colors as a basis for comparison, I don't think you can do it in anywhere near the time you wanted, but it would still be a good learning exercise if that's your main goal.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Is there any way to search for multiple pixels for multiple color??

Post by malcev » 28 Apr 2021, 01:03

Is it possible to check if certain area of my screen (160*90 pixel) contains ANY one of those colors?
Of course it is possible.
Every screen search algorithm consists of 2 parts.
1) Get screen byte array with different API.
2) Search inside this array.
I am too lazy to compare different algorithms now (I was interested with this things about 1.5 years ago), but comparing each color in ARGB of my screen 1920x1080 win10 ahk64bit with array of predefined colors takes about 750ms on my PC.

Code: Select all

SetBatchLines, -1
predefinedColorsArray := []
loop 100
   predefinedColorsArray[A_Index] := 1
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen()
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap)
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)
a := A_TickCount
loop % height
{
   A_IndexY := A_Index-1
   loop % width
   {
      if predefinedColorsArray[NumGet(Scan0+0, (A_Index-1)*4 + A_IndexY*Stride, "uint")]
         n++
   }
}
msgbox % A_TickCount - a "`n" n
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
killmatt01
Posts: 20
Joined: 25 Mar 2021, 00:12
Contact:

Re: Is there any way to search for multiple pixels for multiple color??

Post by killmatt01 » 30 Apr 2021, 23:47

malcev wrote:
28 Apr 2021, 01:03
Is it possible to check if certain area of my screen (160*90 pixel) contains ANY one of those colors?
Of course it is possible.
Every screen search algorithm consists of 2 parts.
1) Get screen byte array with different API.
2) Search inside this array.
I am too lazy to compare different algorithms now (I was interested with this things about 1.5 years ago), but comparing each color in ARGB of my screen 1920x1080 win10 ahk64bit with array of predefined colors takes about 750ms on my PC.

Code: Select all

SetBatchLines, -1
predefinedColorsArray := []
loop 100
   predefinedColorsArray[A_Index] := 1
pToken := Gdip_Startup()
pBitmap := Gdip_BitmapFromScreen()
width := Gdip_GetImageWidth(pBitmap)
height := Gdip_GetImageHeight(pBitmap)
Gdip_LockBits(pBitmap, 0, 0, width, height, Stride, Scan0, BitmapData)
a := A_TickCount
loop % height
{
   A_IndexY := A_Index-1
   loop % width
   {
      if predefinedColorsArray[NumGet(Scan0+0, (A_Index-1)*4 + A_IndexY*Stride, "uint")]
         n++
   }
}
msgbox % A_TickCount - a "`n" n
Gdip_UnlockBits(pBitmap, BitmapData)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
Many thanks! I got that now! @boiler @malcev
Since the area i need to check is small enough, i got 7ms each turn which is awesome!!!
And another funny thing come, which i met previously and it still happens:
https://www.autohotkey.com/boards/viewtopic.php?p=396545#p396545(described in this post)

Well, when i run the get color script as it only allocates 2mb of memory, the cpu usage is around 15%
After i right clicked the tray icon and the script allocated around 100mb of memory, the cpu usage decreased to less than 1.5%
(The area is still 160*90 but it is different location of my screen each time i test it, and average time use each turn is still around 7ms)
So now i want to decrease the cpu usage and i am fine with more memory allocated, is it possible for me to allocate more memory (for the script) at the beginning so the cpu usage will be less than 1.5mb whenever i activate the function? I hope my expression is understandable since i am not a native speaker...
Post Reply

Return to “Ask for Help (v1)”