Converting hex color to RGB and vice-versa

529

Solution 1

Real answer: Depends on what kind of hexadecimal color value you are looking for (e.g. 565, 555, 888, 8888, etc), the amount of alpha bits, the actual color distribution (rgb vs bgr...) and a ton of other variables.

Here's a generic algorithm for most RGB values using C++ templates (straight from ScummVM).

template<class T>
uint32 RGBToColor(uint8 r, uint8 g, uint8 b) {
return T::kAlphaMask |
       (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
       (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
       (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
}

Here's a sample color struct for 565 (the standard format for 16 bit colors):

template<>
struct ColorMasks<565> {
enum {
    highBits    = 0xF7DEF7DE,
    lowBits     = 0x08210821,
    qhighBits   = 0xE79CE79C,
    qlowBits    = 0x18631863,


    kBytesPerPixel = 2,

    kAlphaBits  = 0,
    kRedBits    = 5,
    kGreenBits  = 6,
    kBlueBits   = 5,

    kAlphaShift = kRedBits+kGreenBits+kBlueBits,
    kRedShift   = kGreenBits+kBlueBits,
    kGreenShift = kBlueBits,
    kBlueShift  = 0,

    kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
    kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
    kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
    kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,

    kRedBlueMask = kRedMask | kBlueMask

};
};

Solution 2

In python:

def hex_to_rgb(value):
    """Return (red, green, blue) for the color given as #rrggbb."""
    value = value.lstrip('#')
    lv = len(value)
    return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))

def rgb_to_hex(red, green, blue):
    """Return color as #rrggbb for the given color values."""
    return '#%02x%02x%02x' % (red, green, blue)

hex_to_rgb("#ffffff")           #==> (255, 255, 255)
hex_to_rgb("#ffffffffffff")     #==> (65535, 65535, 65535)
rgb_to_hex(255, 255, 255)       #==> '#ffffff'
rgb_to_hex(65535, 65535, 65535) #==> '#ffffffffffff'

Solution 3

In python conversion between hex and 'rgb' is also included in the plotting package matplotlib. Namely

import matplotlib.colors as colors

Then

colors.hex2color('#ffffff')        #==> (1.0, 1.0, 1.0)
colors.rgb2hex((1.0, 1.0, 1.0))    #==> '#ffffff'

The caveat is that rgb values in colors are assumed to be between 0.0 and 1.0. If you want to go between 0 and 255 you need to do a small conversion. Specifically,

def hex_to_rgb(hex_string):
    rgb = colors.hex2color(hex_string)
    return tuple([int(255*x) for x in rgb])

def rgb_to_hex(rgb_tuple):
    return colors.rgb2hex([1.0*x/255 for x in rgb_tuple])

The other note is that colors.hex2color only accepts valid hex color strings.

Solution 4

just real quick:

int r = ( hexcolor >> 16 ) & 0xFF;

int g = ( hexcolor >> 8 ) & 0xFF;

int b = hexcolor & 0xFF;

int hexcolor = (r << 16) + (g << 8) + b;

Solution 5

Modifying Jeremy's python answer to handle short CSS rgb values like 0, #999, and #fff (which browsers would render as black, medium grey, and white):

def hex_to_rgb(value):
    value = value.lstrip('#')
    lv = len(value)
    if lv == 1:
        v = int(value, 16)*17
        return v, v, v
    if lv == 3:
        return tuple(int(value[i:i+1], 16)*17 for i in range(0, 3))
    return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
Share:
529
atta
Author by

atta

Updated on April 21, 2020

Comments

  • atta
    atta about 4 years

    I want to find the total number of machine instructions of an Android Application. I have explored the Debug.InstructionCount class of Android SDK, but I believe it provides info of Dalvik VM instructions (not the machine level instructions which actually executes on the processor). I need this info to estimate the time required for the execution of an Android application on a particular processor (using fixed frequency). I am aware of the fact that different type of instructions take variable cycles due to which the computational time cannot be estimated accurately, but I still want to do some experimentation. Thank you

    • Adam Davis
      Adam Davis over 15 years
      You might want to define the language. This will make a difference in the algorithm chosen.
    • auselen
      auselen over 10 years
      why don't use just run it on a particular device, time it then guesstimate how long that could take on another device?
  • Jonathan Tran
    Jonathan Tran over 15 years
    He wrote an equation. RGB to hex is reading right to left. Hex to RGB is reading left to right.
  • Adam Rosenfield
    Adam Rosenfield over 15 years
    Careful of your operator precedence: + has higher precedence than <<
  • jciconsult
    jciconsult almost 14 years
    Nice.. answer's been there for 1.5 years and no one caught that.
  • jpmc26
    jpmc26 about 11 years
    Could you explain what's happening in the formatting for rbg_to_hex?
  • java_newbie
    java_newbie about 11 years
    In the function, rgb is a tuple of 3 ints. That format string is just a # followed by three %02x which just gives a zero padded 2 digit hex value of the int.
  • java_newbie
    java_newbie about 11 years
    I posted this so long ago and it's still one of my favorite chunks of python code (that I've written)
  • Richard Stagg
    Richard Stagg almost 11 years
    This is a great find, you don't mind if I use this in some GPL code of mine? :)
  • java_newbie
    java_newbie almost 11 years
    Not at all, as long as you include a link to this answer.
  • old_timer
    old_timer over 10 years
    yes, a sim would have to deal with the real-world number of times through loops related to real hardware delays.
  • artless noise
    artless noise over 10 years
    +1 for trying. Avr or ARM? :). Unfortunately, the instruction count with the simulator maybe data dependent; this is particularly important with Java/Davlik as some instructions are far more expensive (out of bounds, etc) than others. Also, one instruction may affect the execution speed of the next, etc. See: Objdump and ARM cycles, where you took the opposite side. Knowing the limitations is always helpful.
  • old_timer
    old_timer over 10 years
    LOL, I read Android and thought Arduino, but the answer is the same if you want to know how many instructions you are executing (which means in execution order) you have to count them in execution order. Same process if you want to count arm, avr, mips, java bytecode, llvm bitcode, pascal pcode, and so on.
  • old_timer
    old_timer over 10 years
    artless noise the poster is aware of the varying nature of instructions and still just wants an instruction count.
  • Brōtsyorfuzthrāx
    Brōtsyorfuzthrāx over 9 years
    For rgb_to_hex, you can always do *rbg in the argument list if you don't want to have to put a tuple in as a parameter, and it still works fine (causing errors if you don't put in three parameters).
  • Harvey
    Harvey over 9 years
    Um... if int is 16 bits. red is shifted to the bit bucket.
  • jciconsult
    jciconsult over 9 years
    @harvey, entirely true, as would 8-bit be an issue. Not sure how many 16-bit machines have C/Java compilers out there, but I'm sure it's more than when I wrote this answer 6+ years ago.
  • java_newbie
    java_newbie over 7 years
    In hindsight, it seems like rgb_to_hex(r, g, b) makes more sense than it accepting rgb as a tuple. It would make the function definition easier to understand. Yeah?