Easy Question about Colors Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
masheen
Posts: 295
Joined: 06 Dec 2016, 14:10

Easy Question about Colors

11 Aug 2017, 14:22

I have 2 color

Color1 = 0xFF040D4D
Image

Color2 = 0xFF4D040D
Image

How mix it and get this?
Image

ColorResult = 0xFF310825

i need
Color1 - Color2
or Color1 / Color2
or what plz tell me.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Easy Question about Colors

11 Aug 2017, 15:35

Isolate each color (>>operator I think can do this for ya, but I haven't done it that way myself -- it'll be able to shorten up the math though to get it all done in one go -- you also need to do something with the & operator and 0xFF... it's on the forums somewhere).

If you have the values 4D and 04, and if you use SetFormat to do Hexadecimal for your maths. It looks like you want the average, but that doesn't quite work right.

Code: Select all

SetFormat, Integer, H
var1:=0x4D
var2:=0x04
average:=(var1+var2)//2 ; floor divide, otherwise you get an odd number which when divided by 2 becomes a fraction and appears as a decimal.
MsgBox % average
return

Edit:
All this math can be compressed into four lines (or even one if you wanted), and then the concatenation for the final_answer. Probably could do well with a function that takes the inputs and splits into an array or better name variables to do a loop through them. But, whichever. Just a proof of concept.

And jeeswg is right below, we shouldn't use floor divide, because that forces a round down. So Round() is better. The code below reflects that. (Though when it was doing round down, g_avg:=(g1+g2)//2 gave the answer of 0x8 (0x08) which matches up with the third byte in your expected result, OP.)

Code: Select all

!3::
SetFormat, Integer, H
color1:=0xFF040D4D
color2:=0xFF4D040D
a1:=(color1>>(8*3)) & 0xFF
r1:=(color1>>(8*2)) & 0xFF
g1:=(color1>>(8*1)) & 0xFF
b1:=(color1>>(8*0)) & 0xFF
a2:=(color2>>(8*3)) & 0xFF
r2:=(color2>>(8*2)) & 0xFF
g2:=(color2>>(8*1)) & 0xFF
b2:=(color2>>(8*0)) & 0xFF
; you'll notice the values like 0x04 are shown as 0x4 here, but that doesn't hurt the math
MsgBox % a1 "`t" r1 "`t" g1 "`t" b1 "`n" a2 "`t" r2 "`t" g2 "`t" b2
a_avg:=Round((a1+a2)/2)
r_avg:=Round((r1+r2)/2)
g_avg:=Round((g1+g2)/2)
b_avg:=Round((b1+b2)/2)
; then we need to pad them
MsgBox % a_avg "`t" r_avg "`t" g_avg "`t" b_avg
If StrLen(a_avg)=3
   a_avg:=StrReplace(a_avg,"x","x0")
If StrLen(r_avg)=3
   r_avg:=StrReplace(r_avg,"x","x0")
If StrLen(g_avg)=3
   g_avg:=StrReplace(g_avg,"x","x0")
If StrLen(b_avg)=3
   b_avg:=StrReplace(b_avg,"x","x0")
MsgBox % a_avg "`t" r_avg "`t" g_avg "`t" b_avg
; But what we really needed out of that was just the last two digits for each number, getting rid of the 0x prefix
a_avg:=SubStr(a_avg,-1) ; position 0 is last, position -1 is second to last
r_avg:=SubStr(r_avg,-1)
g_avg:=SubStr(g_avg,-1)
b_avg:=SubStr(b_avg,-1)
; and concatenate it
final_answer:="0x" a_avg r_avg g_avg b_avg
MsgBox % final_answer
return
But that only comes up with a final answer of 0xFF29092D, which is off from the desired 0xFF310825 - assuming these are RGB values, the desired value is biased toward red (+0x08) and against blue (-0x08).
Last edited by Exaskryz on 11 Aug 2017, 16:14, edited 1 time in total.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Easy Question about Colors  Topic is solved

11 Aug 2017, 15:58

I've been working recently, with a lot of this type of maths. I've found it quite hard to get this concise:

Code: Select all

q:: ;take average of 2 RGB values based on separate R/G/B values
vCol1 := 0x040D4D
vCol2 := 0x4D040D
vCol3 := Format("0x{:02X}{:02X}{:02X}", Round(((vCol1&0xFF0000)+(vCol2&0xFF0000))/0x20000), Round(((vCol1&0xFF00)+(vCol2&0xFF00))/0x200), Round(((vCol1&0xFF)+(vCol2&0xFF))/2))
MsgBox, % vCol3 ;0x29092D

vCol1 := 0xFF040D4D
vCol2 := 0xFF4D040D
vCol3 := Format("0x{:02X}{:02X}{:02X}{:02X}", Round(((vCol1&0xFF000000)+(vCol2&0xFF000000))/0x2000000), Round(((vCol1&0xFF0000)+(vCol2&0xFF0000))/0x20000), Round(((vCol1&0xFF00)+(vCol2&0xFF00))/0x200), Round(((vCol1&0xFF)+(vCol2&0xFF))/2))
MsgBox, % vCol3 ;0xFF29092D
return
I was tempted to use bitshift, but bitshift rounds down, and any halves when rounded to the nearest integer, should be rounded up.

I also discovered that if you apply the Format function, specifying an integer as the output format, that truncates the integer, instead of rounding it, so I had to use the Round function.

However, it may be possible to improve on my code.

There may be some other algorithm that is calculating your colour 'average', if anyone is familiar with colour averages.

@masheen: If you can mention the program you are using, or provide a link to a website that gives you the same results, that would be useful.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
masheen
Posts: 295
Joined: 06 Dec 2016, 14:10

Re: Easy Question about Colors

12 Aug 2017, 03:08

jeeswg wrote:I've been working recently, with a lot of this type of maths. I've found it quite hard to get this concise:

Code: Select all

q:: ;take average of 2 RGB values based on separate R/G/B values
vCol1 := 0x040D4D
vCol2 := 0x4D040D
vCol3 := Format("0x{:02X}{:02X}{:02X}", Round(((vCol1&0xFF0000)+(vCol2&0xFF0000))/0x20000), Round(((vCol1&0xFF00)+(vCol2&0xFF00))/0x200), Round(((vCol1&0xFF)+(vCol2&0xFF))/2))
MsgBox, % vCol3 ;0x29092D

vCol1 := 0xFF040D4D
vCol2 := 0xFF4D040D
vCol3 := Format("0x{:02X}{:02X}{:02X}{:02X}", Round(((vCol1&0xFF000000)+(vCol2&0xFF000000))/0x2000000), Round(((vCol1&0xFF0000)+(vCol2&0xFF0000))/0x20000), Round(((vCol1&0xFF00)+(vCol2&0xFF00))/0x200), Round(((vCol1&0xFF)+(vCol2&0xFF))/2))
MsgBox, % vCol3 ;0xFF29092D
return
I was tempted to use bitshift, but bitshift rounds down, and any halves when rounded to the nearest integer, should be rounded up.

I also discovered that if you apply the Format function, specifying an integer as the output format, that truncates the integer, instead of rounding it, so I had to use the Round function.

However, it may be possible to improve on my code.

There may be some other algorithm that is calculating your colour 'average', if anyone is familiar with colour averages.

@masheen: If you can mention the program you are using, or provide a link to a website that gives you the same results, that would be useful.

thx. Can u tell me how i can to know grayscale color or not?
example i have color 0xFF5D5D5D
how to do?
if R = G = B = Grayscale
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Easy Question about Colors

12 Aug 2017, 07:02

This should do it:

Code: Select all

q:: ;check if R/G/B values are equal to each other
vCol := 0xFF5D5D5D
;vCol := 0xFF5D5D5E
;vCol := 0x5D5D5D
;vCol := 0x5D5D5E

if ((vCol>>16)&0xFF = vCol&0xFF) && ((vCol>>8)&0xFF = vCol&0xFF)
	MsgBox, % "y"
else
	MsgBox, % "n"
return
Last edited by jeeswg on 13 Aug 2017, 07:23, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
masheen
Posts: 295
Joined: 06 Dec 2016, 14:10

Re: Easy Question about Colors

13 Aug 2017, 00:36

jeeswg wrote:This should do it:

Code: Select all

q:: ;check if R/G/B values are equal to each other
vCol := 0xFF5D5D5D
;vCol := 0xFF5D5D5E

if ((vCol>>16)&0xFF = vCol&0xFF) && ((vCol>>8)&0xFF = vCol&0xFF)
	MsgBox, % "y"
else
	MsgBox, % "n"
return
thx work goood.
Last question if i have color without alpha like this 0x5D5D5D
can u help?
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Easy Question about Colors

13 Aug 2017, 05:49

I found two interesting articles: Both don't retrieve the result you posted in the OP (0x310825). The first one is a fast replacement for the methods posted by Exaskryz and jeeswg but is rounding down by design.

Code: Select all

#NoEnv
Color1 := 0x040D4D
Color2 := 0x4D040D
Color3 := Format("0x{:06X}", Average1(Color1, Color2)) ; 0x28082D
Color4 := Format("0x{:06X}", Average2(Color1, Color2)) ; 0x370A37
Color5 := 0x310825 ; the value from your first post
Gui, Margin, 1, 1
Gui, Font, s16
Gui, Add, Progress, w600 h100 Background%Color1%
Gui, Add, Text, xp yp wp hp cWhite Center +0x200 +BackgroundTrans, %Color1%
Gui, Add, Progress, w600 h100 Background%Color2%
Gui, Add, Text, xp yp wp hp cWhite Center +0x200 +BackgroundTrans, %Color2%
Gui, Add, Progress, w600 h100 Background%Color3%
Gui, Add, Text, xp yp wp hp cWhite Center +0x200 +BackgroundTrans, Average1: %Color3%
Gui, Add, Progress, w600 h100 Background%Color4%
Gui, Add, Text, xp yp wp hp cWhite Center +0x200 +BackgroundTrans, Average2: %Color4%
Gui, Add, Progress, w600 h100 Background%Color5%
Gui, Add, Text, xp yp wp hp cWhite Center +0x200 +BackgroundTrans, Your result: %Color5%
Gui, Show, , Test
Return
GuiClose:
ExitApp

Average1(Color1, Color2) {
   ; www.compuphase.com/graphic/scale3.htm, modified to work only on the RGB part of an ARGB
   Return (((Color1 ^ Color2) & 0xFEFEFE) >> 1) + (Color1 & Color2 & 0xFFFFFF)
}

Average2(Color1, Color2) {
   ; medium.com/@kevinsimper/how-to-average-rgb-colors-together-6cd3ef1ff1e5
   R := Round(Sqrt(((R(Color1)**2) + (R(Color2)**2)) / 2))
   G := Round(Sqrt(((G(Color1)**2) + (G(Color2)**2)) / 2))
   B := Round(Sqrt(((B(Color1)**2) + (B(Color2)**2)) / 2))
   Return RGB(R, G, B)
}

R(Color) {
   Return (Color >> 16) & 0xFF
}
G(Color) {
   Return (Color >> 8) & 0xFF
}
B(Color) {
   Return (Color & 0xFF)
}
RGB(R, G, B) {
   Return ((R & 0xFF) << 16) | ((G & 0xFF) << 8) | (B & 0xFF)
}
You have the agony of choice!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Easy Question about Colors

13 Aug 2017, 07:27

@masheen: I wrote it in such a way that it handles RGB values with/without an alpha value. If you look over the code you will see that it doesn't matter whether the value has a alpha value or not.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: aitaixy, Anput, Nerafius, RandomBoy and 185 guests