Need inverse of RGB(r,g,b)

N

Neil Humphries

The RGB function returns a colour number. I need a function that will take a
colour number as input and return the equivalent RGB specification.

I need to use custom colours within a Word document and corresponding
colours in menu icons. I only have colour numbers (e.g. 683250 and 1900708)
for the colours, but the software available to me for creating icons requires
I input in RGB format.

Is there a way to do this in VBA or is there software that will convert for
me?
 
J

Jay Freedman

Neil said:
The RGB function returns a colour number. I need a function that will
take a colour number as input and return the equivalent RGB
specification.

I need to use custom colours within a Word document and corresponding
colours in menu icons. I only have colour numbers (e.g. 683250 and
1900708) for the colours, but the software available to me for
creating icons requires I input in RGB format.

Is there a way to do this in VBA or is there software that will
convert for me?

You can do it in VBA.

First, an explanation of how it works: Going from RGB to a single number,
the three numbers from the RGB representation are converted to hexadecimal
and then stuck together, with the R number in the least significant
position, two hex digits each. That 6-digit hex number is then converted
back to decimal. For example, if the RGB colour is 242 red, 108 green, 10
blue then in hex you have

R = 242 decimal = F2 hex
G = 108 decimal = 6C hex
B = 10 decimal = 0A hex

colour number = 0A6CF2 hex = 683250 decimal

To reverse the procedure, take the decimal colour number and convert it to a
6-digit hex number; take each 2-digit piece of the hex number and convert it
to the corresponding decimal number.

Here's the VBA code:

Sub ColourToRGB()
Dim strColour As String
Dim hexColour As String
Dim nColour As Long
Dim nR As Long, nB As Long, nG As Long

strColour = InputBox("Enter decimal colour number:")
If Len(strColour) = 0 Then Exit Sub

nColour = Val(strColour) ' convert string to decimal number
hexColour = Hex(nColour) ' convert decimal number to hex string
While Len(hexColour) < 6 ' pad on left to 6 hex digits
hexColour = "0" & hexColour
Wend

nB = CLng("&H" & Mid(hexColour, 1, 2))
nG = CLng("&H" & Mid(hexColour, 3, 2))
nR = CLng("&H" & Mid(hexColour, 5, 2))

MsgBox strColour & " = R " & nR & ", G " & nG & ", B " & nB
End Sub


--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
T

Tony Jollans

The RGB function creates a number, which is 256*256*Blue + 256*Green + Red

For example, RGB(242, 108, 10) returns 256*256*10 (=655360) + 256*108
(=27648) + 242 = 683250, so what you have to do is reverse this. There are
various ways to do it, but the easiest is to use hexadecimal numbers.

Using hex for the same RGB value: hex(242) = F2, hex(108) = 6C, hex(10) =
0A, and, for the calculation, Hex(256) = 100. So RGB(&HF2, &H6C, &HA)
returns &H100 * &H100 * &HA (=&HA0000) + &H100 * &H6C (=&H6C00) + &HF2 =
&HA6CF2 (which is 683250, decimal).

To reverse the process, first get the hex value as a six digit hex number
(adding leading zeroes if necessary): Hex(683250) = 0A6CF2, then split it
into three two-digit hex numbers: 0A (blue), 6C (green), F2 (red), nad then
convert to decimal if you want.

Some code:

Dim RGBHex As String
Dim Blue As Long, Green As Long, Red As Long

RGBHex = Right("000000" & Hex(683250), 6)

Blue = "&H" & Mid(RGBHex, 1, 2)
Green = "&H" & Mid(RGBHex, 3, 2)
Red = "&H" & Mid(RGBHex, 5, 2)

MsgBox "Red: " & Red & ", Green: " & Green & ", Blue: " & Blue
 
N

Neil Humphries

Both responses unpack how the RGB function works which is great.

I wrote an Excel function to display the output of the VBA RGB function:
Function ColourNum(r, g, b)
ColourNum = RGB(r, g, b)
End Function

Then I used the formulas below in 3 columns:
=HEX2DEC(MID(TEXT(DEC2HEX($E$14,6),"000000"),5,2))
=HEX2DEC(MID(TEXT(DEC2HEX($E$14,6),"000000"),3,2))
=HEX2DEC(MID(TEXT(DEC2HEX($E$14,6),"000000"),1,2))
where E14 is the colour number.

This displays the R, G, B values of the colour number.

hex2dec and dec2hex may be part of the Analysis Toolpack for Excel

Now I can convert either way.

Thanks for your help.
 
K

Karl E. Peterson

Neil said:
The RGB function returns a colour number. I need a function that will take a
colour number as input and return the equivalent RGB specification.

The absolute most efficient method to do this would be along these lines:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination
As Any, Source As Any, ByVal Length As Long)

Public Type RGB32
Red As Byte
Green As Byte
Blue As Byte
Pad As Byte
End Type

Public Function SplitColors(ByVal Value As Long) As RGB32
Call CopyMemory(SplitColors, Value, 4)
End Function

Boom! One call. Done. If you'd just like to pull individual values from an RGB,
there's no need to mess around with strings, either. You can "just do the math" as
follows:

Public Function Red(ByVal Value As Long) As Byte
Red = (Value Mod &H100)
End Function

Public Function Green(ByVal Value As Long) As Byte
Green = (Value \ &H100) Mod &H100
End Function

Public Function Blue(ByVal Value As Long) As Byte
Blue = (Value \ &H10000) Mod &H10000
End Function

Or, to fully emulate the native C macros:

Public Function GetRValue(ByVal Value As Long) As Byte
' #define GetRValue(rgb) ((BYTE) (rgb))
GetRValue = (Value And &HFF)
End Function

Public Function GetGValue(ByVal Value As Long) As Byte
' #define GetGValue(rgb) ((BYTE) (((WORD) (rgb)) >> 8))
GetGValue = (Value And &HFF00&) \ &H100
End Function

Public Function GetBValue(ByVal Value As Long) As Byte
' #define GetBValue(rgb) ((BYTE) ((rgb) >> 16))
GetBValue = (Value And &HFF0000) \ &H10000
End Function

Fun, huh? :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top