# A question of color...(not a racial question)

• 01-15-2003
Sebastiani
A question of color...(not a racial question)
Erm, ok. I have a COLORREF. I need to separate the RGB values from it, and produce two things: The "opposite" of that color. A more grayed version of that color. Getting the three RGB's shouldn't be difficult, I'll just use bit shifting. My main problem is determining the the two extra colors. Any ideas?
• 01-15-2003
By the opposite of the colour I assume that if you give white you want black. That being so, the colours are stored as 0-255 of each red, green and blue - subtract each colour component from 255 and assemble a COLORREF from the results. In the black white example:

White

Red 255
Green 255
Blue 255

255 - Red = 0
255 - Green = 0
255 - Blue = 0

0,0,0 = Black.

To reduce the intensity of a colour, subtract an amount from each colour component, (make sure you don't go negative). A simple solution would be to subtract, say, 50 from each colour. Another approach would be to reduce each of the components by the same percentage.

White = 255,255,255 subtract 50 from each, 205,205,205 = light grey.
• 01-15-2003
Sebastiani
Thank you for the input. That was the push I needed. :) Cheers.
• 01-15-2003
LuckY
FYI, Sebatiani, there are built-in macros you can use to get the R, G, and B values out of a COLORREF struct:

BYTE GetRValue(WORD rgb);
BYTE GetGValue(WORD rgb);
BYTE GetBValue(WORD rgb);

*LuckY*
• 01-15-2003
Sebastiani
Thanks, I didn't find those. These work too.

Code:

```int Red(COLORREF color){  return (int)(( color << 24 ) >> 24); } int Green(COLORREF color){  return (int)(( color << 16 ) >> 24); } int Blue(COLORREF color){  return (int)(( color << 8 ) >> 24); } bool IsPalette(COLORREF color){  return ((color >> 24) & 0x02); }```
• 01-15-2003
Sebastiani
Here's a solution that works exceptionally well. Average the three colors. Assign the average to all but the highest valued color. This doesn't account for colors having the same value, but this demonstrates a temporary solution to that case.

Code:

```// sample the center of the image //     COLORREF pixel = buff.Pixel(width/2, height/2);     int r = Red(pixel);     int g = Green(pixel);     int b = Blue(pixel);     int average = (r+b+g)/3;         if(r > g && r > b) g = b = average;         else if(g > r && g > b) r = b = average;         else if(b > r && b > g) r = g = average;         else       {        // temporary solution to gray images //         r = g = b = average >= 127 ? average - 64 : average + 64;       }     bool ip = IsPalette(pixel);     COLORREF replace = ip ? PALETTERGB(r,g,b) : RGB(r,g,b);         for(int i = 0; i < width; ++i)           for(int j = 0; j < height; ++j)             if(buff.Pixel(i, j) == pixel)                 buff.Pixel(i, j, replace);```
• 01-15-2003
Sang-drax
I have a better way (let's not reinvent the wheel :) ):

*Convert the color to (hue, saturation, lightness) using
ColorRGBToHLS()

*Change saturation (for "grayness" or contrast) and lightnesss as desired

*Convert back using
ColorHLSToRGB()

This function is unavailable in Windows 95.

Info:
http://exchange.manifold.net/manifol...on_and_Bri.htm
Conversion (for Win95 users) :
http://astronomy.swin.edu.au/~pbourk...onversion.html
• 01-15-2003
Sebastiani
Excellent! That's exactly what I was looking for.
Thanks SangDrax. :)