Thread: A question of color...(not a racial question)

  1. #1
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708

    Post 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?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  2. #2
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    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.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Thank you for the input. That was the push I needed. Cheers.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    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*

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    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); 
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    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);
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    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
    Last edited by Sang-drax; 01-15-2003 at 06:45 PM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Excellent! That's exactly what I was looking for.
    Thanks SangDrax.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-04-2005, 12:17 AM
  2. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  3. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  4. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  5. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM