Convert from HEX color to RGB struct in C

前端 未结 5 1067
忘了有多久
忘了有多久 2020-12-15 11:07

How do you convert from color HEX code to RGB in pure C using C library only (without C++ or templates)? The RGB struct may be like this:



        
相关标签:
5条回答
  • 2020-12-15 11:36

    Assuming that your hex value is a 32-bit 'int' type, and that we use the RGB struct described above, then maybe do something like:

    struct RGB colorConverter(int hexValue)
    {
      struct RGB rgbColor;
      rgbColor.r = ((hexValue >> 16) & 0xFF) / 255.0;  // Extract the RR byte
      rgbColor.g = ((hexValue >> 8) & 0xFF) / 255.0;   // Extract the GG byte
      rgbColor.b = ((hexValue) & 0xFF) / 255.0;        // Extract the BB byte
    
      return rgbColor; 
    }
    
    0 讨论(0)
  • 2020-12-15 11:38

    An RGB value can be stored as in integer via 0xRRGGBB. Examples:

    • Red: 0xff0000
    • Green: 0x00ff00
    • Blue: 0x0000ff

    00 is hex for decimal 0, while ff is 255. 0 corresponds to 0.0 and 255 to 1.0. (Actually you didn't specify what the range is. I'm assuming 0.0 to 1.0.)

    So with the above assumptions, you need to extract each component and divide by 255. Since it sounds a lot like a homework question, I'll just show you how you can do the red component.

    int hex = 0x123456;
    c.r = ((hex >> 16) & 0xff) / 255.0;
    

    Each hex digit takes up 4 bits. So shift to the right by 16 bits (to move everything 4 digits to the right) to make 0xRRGGBB become 0xRR. Now you have the red component. (Just in case there is some data higher up in the integer, you can get rid of it by masking the data via & 0xff.)

    If you are dealing with a string "#FFFFFF", then you'd first have to convert it to an integer for the above to work.

    0 讨论(0)
  • 2020-12-15 11:40

    I guess RGB could be stored as 0xRRGGBB on some systems, but in Windows it is actually stored as 0xBBGGRR (see http://msdn.microsoft.com/en-us/library/windows/desktop/dd183449). As the article mentions, there are macros GetRValue, GetGValue, and GetBValue already available.

    0 讨论(0)
  • 2020-12-15 11:45

    If the hex code is a string, you can parse it like this

    char *str = "0000FF";
    int r, g, b;
    sscanf(str, "%02x%02x%02x", &r, &g, &b);
    

    That is to ints, not doubles. Also do check that sscanf returns 3, the number of items read.

    0 讨论(0)
  • 2020-12-15 11:59

    I know this is quite old, but I wanted to give also a solution with unions and without any bitwise operations.

    union Color
    {
        unsigned int hex;
        struct { unsigned char b, g, r; };
    };
    

    This way you can convert from HEX to RGB and from RGB to HEX, easily.

    union Color hex;
    hex.hex = 0x07C73C;
    
    union Color rgb;
    rgb.r = 7;
    rgb.g = 199;
    rgb.b = 60;
    
    printf("RGB(%d, %d, %d), HEX(%06x)", hex.r, hex.g, hex.b, rgb.hex);
    

    Output:

    RGB(7, 199, 60), HEX(07c73c)
    

    and to map the values in the range of 0.0 to 1.0 you simply divide it by 255.0 :)

    EDIT: The code above^^ is only supported under Little-Endian CPU's architecture, so a better way is to check what endianness does the system runs on.

    Then you can check the endianness to define the order of the struct variables.

    union Color
    {
        unsigned int hex;
    
    #if IS_BIG_ENDIAN
        struct { unsigned char a, r, g, b; };
    #else
        struct { unsigned char b, g, r, a; };
    #endif
    };
    

    This code also supports alpha ( transparency ) in RGBA.

    0 讨论(0)
提交回复
热议问题