I want to scan a given region for the 6 most common colors

Get help with using AutoHotkey and its commands and hotkeys
User avatar
Off Topic
Posts: 43
Joined: 07 Oct 2017, 20:57

I want to scan a given region for the 6 most common colors

25 Apr 2018, 01:49

And a given region from a mouse click and drag, but I'm not sure how the scanning part and comparing colors would be best done. I figure that I would need to loop through a grid whose dimensions are based on the width and height of the clickdrag and PixelGetColor each, then add distinct colors to a string and compare how many instances each had within this scanned region to determine the 6 most common. I think I'm off to a decent start but I don't know how to approach how many instances of color there were or how to best cycle through "scan lines" to check for color:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



Can I get any help? How would you personally do this, retrieving the six most common colors for any given region?
MaxAstro
Posts: 550
Joined: 05 Oct 2016, 13:00

Re: I want to scan a given region for the 6 most common colors

25 Apr 2018, 11:15

First off, for the love of all that is holy, use GDI+ instead of PixelGetColor, your script will be about a hundred times faster. GDI+ libraries attached.

Secondly, what I would probably do is check the color of each pixel in the area one at a time and build an array. Use the color as the key and the number of times you've seen that color as the value. Each time you scan a pixel, check the array to see if that key exists. If it doesn't, add it, if it does increment the value by one.

Once you've finished searching, you now have an array containing the number of occurrences of each color, and it should be easy to for-loop through that array and sort out the six highest.
Attachments
Gdip_PixelSearch.ahk
(1.02 KiB) Downloaded 13 times
Gdip_ImageSearch.ahk
(33.25 KiB) Downloaded 11 times
Gdip_All.ahk
(95.45 KiB) Downloaded 14 times
User avatar
jeeswg
Posts: 4504
Joined: 19 Dec 2016, 01:58
Location: UK

Re: I want to scan a given region for the 6 most common colors

25 Apr 2018, 12:36

To select a screen region:
selection rectangle: use mouse to select screen region - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=42810

To printscreen a section of the screen, and get a list of pixel colours:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Rohwedder
Posts: 1017
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: I want to scan a given region for the 6 most common colors

26 Apr 2018, 03:23

Hallo,
Hotkey c starts the color measurement.
Try:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

User avatar
sooyke
Posts: 7
Joined: 21 Apr 2018, 10:23

Re: I want to scan a given region for the 6 most common colors

26 Apr 2018, 06:04

Image

Just for fun...

I made the screen area fixed in all codes to 300,300,20,20 and removed msgboxes and tooltips to compare them.

update:

Rohwedder's code using pixelgetcolor is very slow ( on win10) i tried a simple loop 1000 on winXP 32ms on win10 20000 ms!!!!!

The code is rather messy because of copy/paste from separate codes :)

Code: [Select all] [Expand] [Download] (me.ahk)GeSHi © Codebox Plus

swagfag
Posts: 739
Joined: 11 Jan 2017, 17:59

Re: I want to scan a given region for the 6 most common colors

26 Apr 2018, 16:40

jeeswg wrote:

Code: [Select all] [Download] GeSHi © Codebox Plus

; ...
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap2)
VarSetCapacity(DIBSECTION, vSizeDS:=A_PtrSize=8?104:84, 0)
DllCall("gdi32\GetObject", Ptr,hBitmap, Int,vSizeDS, Ptr,&DIBSECTION)
vAddr := NumGet(DIBSECTION, A_PtrSize=8?24:20, "Ptr") ;bmBits
vSize := NumGet(DIBSECTION, A_PtrSize=8?52:44, "UInt") ;biSizeImage
vHex := JEE_StrBinToHex(vAddr, vSize)
; ...


where tf do u come up with this shit, legit question

anyway, heres my go, done pixel by pixel the dumb way, using lockbits and arrays
youll need https://github.com/mmikeww/AHKv2-Gdip/b ... ip_All.ahk
and
noise.png
(1.97 MiB) Not downloaded yet

inside script folder

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



torture_20x20_results.PNG
torture_20x20_results.PNG (70.32 KiB) Viewed 273 times
torture_20x20_bench.PNG
torture_20x20_bench.PNG (65.63 KiB) Viewed 273 times


takes me about 14sec to run the 1080p color noise torture test with an i5 4690k@4.4ghz

on a side note, took me about an hour of trial/error to figure this shit out:

Code: [Select all] [Download] GeSHi © Codebox Plus

numericStringKey := "0xC0FFEE"
array := {}
array[numericStringKey . ""] := "more undocumented v1 idiosyncrasies"
User avatar
jeeswg
Posts: 4504
Joined: 19 Dec 2016, 01:58
Location: UK

Re: I want to scan a given region for the 6 most common colors

26 Apr 2018, 18:26

- @swagfag: In the past I'd tried to retrieve pixel info one pixel at a time, via PixelGetColor or the Gdip library's Gdip_GetPixel, but that seemed slow. I imagined that it would be faster to get the binary data for all of the pixels and convert it to hex, and parse it.
- The Gdip library allows you to save the data as a bmp (via Gdip_SaveBitmapToFile), and I could parse the file, although I'd have to understand bmps to know where the pixel data began. Bmp files start with structs e.g. DIBSECTION, and part of the information in the structs tells you where the data starts.
graphics: create bmp files from scratch - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=34952
- Common possibilities for storing colour data include: 4 bytes per pixel (BGRA where A is transparency), 3 bytes per pixel (BGR, blue/green/red), 1 byte per pixel (look it up in a lookup table of 256 colours), 1/2 byte per pixel (look it up in a lookup table of 16 colours), 1/8 byte = 1 bit per pixel (0 or 1, black or white).
- The simplest data to parse is 4-bytes-per-pixel BGRA data, this is because with other types of bmp, you get meaningless padding data, since file formats like to keep information in multiples of 4 bytes etc.
- It would seem plausible that instead of saving a file to disk first, there might be a more direct method to get hold of the bmp data. So I looked around, including investigating the Gdip library, I'm not sure where I found the answer eventually.
- Another thing to investigate would be the clipboard and clipboard formats, including image data. The clipboard e.g. for MS Paint, must be storing the image data somehow.
Last edited by jeeswg on 26 Apr 2018, 18:53, edited 1 time in total.
swagfag
Posts: 739
Joined: 11 Jan 2017, 17:59

Re: I want to scan a given region for the 6 most common colors

26 Apr 2018, 18:46

yeah i mean if u stop and think about what a bitmap actually is, it might eventually down upon one to skip the headers and read pixel data directly, but damn, never in a million years wouldve occurred to me

good effort man
User avatar
Off Topic
Posts: 43
Joined: 07 Oct 2017, 20:57

Re: I want to scan a given region for the 6 most common colors

26 Apr 2018, 21:42

Hey guys, thank you for all the replies and examples! I didn't expect this much and feel I'm going to need a few days to digest all of it, but I appreciate all the code given and have already tinkered with each. I'm going to try to get each to work and come at you individually for questions.

For a bit more context, I'm trying to use this on vector palettes like this one:

ScanTest.png
ScanTest.png (1.06 KiB) Viewed 227 times


So the amount of colors inside this click-drag region is going to be very low -- probably never more than 10. It's meant to be a way to snatch palettes and place the colors into a gui which I can use keys to then send into Illustrator as the active color (rather than individually using the eyedropper and clicking on each color every single time):

Image

In the above, I'm using PixelGetSearch for mouse position and it works well enough to drag over colors, but I'd like the ability to click and drag a region and instantly snatch all of them (excluding the color I start the click on, which would be the background color) for this gui or in general, which is why I'm asking for the most common 6 colors of a given region. To be honest, I've never touched GDIP before so a lot of this is a bit over my head and kind of daunting, I'm unsure of what I can and can't (or should and shouldn't) modify -- I've tried modifying them but I keep returning bad results or crashing AHK.

jeeswg wrote:To select a screen region:
selection rectangle: use mouse to select screen region - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=42810


Thanks for this! I was planning on doing something similar after figuring this part out, but admittedly I'm having no luck trying to merge InputRect() with your other sample:

Image

So I can retrieve the dimensions correctly, but when I try to implement those dimensions into your sample (rather than the hard-coded ones you had) and run the color scan after the InputRect() ends then everything's showing up blank. It's a bit difficult to understand a code with this many working parts and things I'm unfamiliar with like GDIP, can you look this over and see what I'm doing incorrectly? I started a clean version of your sample and tried to modify as little as possible with comments where I've made changes:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

swagfag
Posts: 739
Joined: 11 Jan 2017, 17:59

Re: I want to scan a given region for the 6 most common colors

27 Apr 2018, 05:46

Image

ive copypasted #LButton::, Scan: and InputRect() from your script and amended mine to include a bunch of other functions

Code: [Select all] [Download] GeSHi © Codebox Plus

/*
when passed an array of coordinates [x, y, w, h]
returns a data structure containing the specifien N most dominant colors,
from the region enclosed by the specified coordinates
*/

getDominantColorFromRegion(numDominantColors, region)


returns an object sorted in ascending order of the type:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



on a side note this rect selection script is giving me real wonky results, occasionally releasing my LButton and producing bogus coordinates, id look into using something else
nvm, i think my LMB switch might be dieing

GDIP_LockBits_DominantColor.ahk
(8.1 KiB) Downloaded 8 times

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


Return to “Ask For Help”

Who is online

Users browsing this forum: Nelson3494 and 31 guests