Getting the most common color from an area

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
lamarcgasolridge
Posts: 15
Joined: 25 Apr 2017, 16:06

Getting the most common color from an area

18 Sep 2017, 04:12

Hello, I am trying to search an area (in my case, a line of pixels 100x1), in order to find the most common exact color in that area.

Here's an example, pretend it is 10x1 pixels:

Image

Red is the most common color (0xdb5b5b, I need exact). Is there a function out there that can do this? I could probably figure out a solution with a bunch of pixelgetcolors, if/thens, and then create some system with variables, but it might not be the most efficient.
lamarcgasolridge
Posts: 15
Joined: 25 Apr 2017, 16:06

Re: Getting the most common color from an area

18 Sep 2017, 04:18

Or maybe this is a start:

(Assume pixel1, pixel2, etc, are the variables)

pixelgetcolor pixel1 = red
pixelgetcolor pixel2 = red
pixelgetcolor pixel3 = green
pixelgetcolor pixel4 = red
pixelgetcolor pixel5 = red
pixelgetcolor pixel6 = blue
pixelgetcolor pixel7 = blue
pixelgetcolor pixel8 = blue
pixelgetcolor pixel9 = green
pixelgetcolor pixel10 = red

So now I have all these variables. How could I count how many variables equal each color, and then the most would be the most common color?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Getting the most common color from an area

18 Sep 2017, 12:08

Try this. Based on:
Gdip: image binary data to hex string for OCR - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 71#p168571

Code: Select all

;[Gdip functions]
;GDI+ standard library 1.45 by tic - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=6517

q:: ;gdip - count pixels of each colour
RegRead, vPath, HKEY_CURRENT_USER\Control Panel\Desktop, Wallpaper
pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(vPath)
Gdip_GetDimensions(pBitmap, vImgW, vImgH)
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
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_BinDataToHex(vAddr, vSize)
DeleteObject(hBitmap)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)

;data is of the form: 'BBGGRRAA'
;to remove transparency bytes:
vText := RegExReplace(vHex, "(.{6})(..)", "$1,")
;to keep transparency bytes:
;vText := RegExReplace(vHex, ".{8}", "$0,")

vText := RTrim(vText, ",")
Sort, vText, D,
oArray := {}
Loop, Parse, vText, % ","
{
	if !oArray.HasKey("" A_LoopField)
		oArray["" A_LoopField] := 1
	else
		oArray["" A_LoopField] += 1
}
vArea := vImgW * vImgH

;===============
;diagnostic
if 0
{
	vCount := 0
	for vKey, vValue in oArray
		vCount += vValue
	MsgBox, % (vCount = vArea) "`r`n" vCount "`r`n" vArea
}
;===============

vOutput := ""
vFormat := "{:0" StrLen(vArea) "}"
for vKey, vValue in oArray
	vOutput .= Format(vFormat, vValue) "`t" vKey "`n"
Sort, vOutput
vOutput := RegExReplace(vOutput, "(^|`n)0*", "$1") ;remove leading zeros
vOutput := StrReplace(vOutput, "`n", "`r`n")
vOutput := StrReplace(vOutput, "`t", "`t0x")
Clipboard := vOutput
oArray := ""
MsgBox, % "done"
return

;==================================================

JEE_BinDataToHex(vAddr, vSize)
{
	;CRYPT_STRING_HEX := 0x4 ;to return space/CRLF-separated text
	;CRYPT_STRING_HEXRAW := 0xC ;to return raw hex (not supported by Windows XP)
	DllCall("crypt32\CryptBinaryToString", Ptr,vAddr, UInt,vSize, UInt,0x4, Ptr,0, UIntP,vChars)
	VarSetCapacity(vHex, vChars*2, 0)
	DllCall("crypt32\CryptBinaryToString", Ptr,vAddr, UInt,vSize, UInt,0x4, Str,vHex, UIntP,vChars)
	vHex := StrReplace(vHex, "`r`n")
	vHex := StrReplace(vHex, " ")
	return vHex
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lamarcgasolridge
Posts: 15
Joined: 25 Apr 2017, 16:06

Re: Getting the most common color from an area

18 Sep 2017, 12:37

Thanks for the link. I actually just found a solution, but I will try your suggestion out.

This was my solution:

Code: Select all

...
allpixels=%pixel1%%pixel2%%pixel3%%pixel4%%pixel5%%pixel6%%pixel7%%pixel8%%pixel9%%pixel10%
colorpixel:="FF0000"

thecount := count(allpixels, colorpixel)
msgbox, %thecount%
return

Count(H, N) {
Pos := 0, Count := 0
Loop
If (Pos := InStr(H, N, False, Pos + 1))
Count++
else
break
return Count
}
https://autohotkey.com/board/topic/5704 ... -variable/

Basically I create one super long variable with the colors back-to-back, and then searched for how many times the color string appears. 0xFF00000xFF00000xFF00000xFF90000xFF90000xFFD2000xFFD2000xFFD2000x000CFF0xFF00000

Though this works for me because I already know what colors I am looking for.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: jameswrightesq, wpulford and 407 guests