I'd like to convert a hex triplet to an RGB tuple and then convert a tuple to a hex triplet.
-
Possible duplicate: http://stackoverflow.com/questions/2262100/rgb-int-to-rgb-python – littlegreen Nov 28 '10 at 09:58
-
1See http://stackoverflow.com/questions/214359/converting-hex-to-rgb-and-vice-versa#214657 – Benjamin Wohlwend Nov 28 '10 at 09:59
-
For Python 3 you want the `bytes`-based answers below by @Inti - clean, fast, no imports, no installs. https://stackoverflow.com/a/51556962/507544 – nealmcb Feb 28 '21 at 02:04
10 Answers
>>> import struct
>>> rgbstr='aabbcc'
>>> struct.unpack('BBB',rgbstr.decode('hex'))
(170, 187, 204)
and
>>> rgb = (50,100,150)
>>> struct.pack('BBB',*rgb).encode('hex')
'326496'

- 45,184
- 7
- 50
- 57
-
9In python 3.0, replace `str.decode('hex')` with `bytes.fromhex(str)` . For the other direction, use `binascii.hexlify` to convert back to a string after packing. – Brian Nov 28 '10 at 10:26
-
1In Python 2.7 `str` is the name of a built-in type. This is also true in many earlier versions, I just don't recall offhand when it was introduced. Anyway, the point is that giving a variable that name isn't generally a good practice because it hides the type. This is still a good answer, IMHO. – martineau Nov 28 '10 at 11:56
-
1Converting this to work in Python 3.x is somewhat tricky -- especially (and surprisingly) the conversion to a hex triplet in the second part. – martineau Mar 29 '14 at 02:38
-
3If I'm not mistaken, `binascii.hexlify` yields a bytes object. You'd need to call `.decode('utf-8')` on that to get a string, right? The total command is `binascii.hexlify(struct.pack('BBB', *rgb)).decode('utf-8')`. I think `'#%02x%02x%02x' % rgb` is a lot simpler, and has the benefit of dealing with float values as well as integers. – rjh May 01 '15 at 07:55
Trying to be pythonic:
>>> rgbstr='aabbcc'
>>> tuple(ord(c) for c in rgbstr.decode('hex'))
(170, 187, 204)
>>> tuple(map(ord, rgbstr.decode('hex'))
(170, 187, 204)
and
>>> rgb=(12,50,100)
>>> "".join(map(chr, rgb)).encode('hex')
'0c3264'

- 819
- 5
- 11
I found a simple way:
red, green, blue = bytes.fromhex("aabbcc")

- 96,623
- 33
- 114
- 148
-
This is the simplest solution out here, that doesn't even require importing any modules. – unfa May 26 '17 at 08:04
-
5
-
This is not only simpler, it's also faster than using struct. More so if you return tuple instead of list. – Marcel Wilson Jul 26 '17 at 17:39
You can use a look-up table with some slicing and shifts — all relatively fast operations — to create a couple of functions that will work unchanged in both Python 2 and 3:
_NUMERALS = '0123456789abcdefABCDEF'
_HEXDEC = {v: int(v, 16) for v in (x+y for x in _NUMERALS for y in _NUMERALS)}
LOWERCASE, UPPERCASE = 'x', 'X'
def rgb(triplet):
return _HEXDEC[triplet[0:2]], _HEXDEC[triplet[2:4]], _HEXDEC[triplet[4:6]]
def triplet(rgb, lettercase=LOWERCASE):
return format(rgb[0]<<16 | rgb[1]<<8 | rgb[2], '06'+lettercase)
if __name__ == '__main__':
print('{}, {}'.format(rgb('aabbcc'), rgb('AABBCC')))
# -> (170, 187, 204), (170, 187, 204)
print('{}, {}'.format(triplet((170, 187, 204)),
triplet((170, 187, 204), UPPERCASE)))
# -> aabbcc, AABBCC
print('{}, {}'.format(rgb('aa0200'), rgb('AA0200')))
# -> (170, 2, 0), (170, 2, 0)
print('{}, {}'.format(triplet((170, 2, 0)),
triplet((170, 2, 0), UPPERCASE)))
# -> aa0200, AA0200

- 119,623
- 25
- 170
- 301
with matplotlib
matplotlib uses RGB tuples with values between 0 and 1:
from matplotlib.colors import hex2color, rgb2hex
hex_color = '#00ff00'
rgb_color = hex2color(hex_color)
hex_color_again = rgb2hex(rgb_color)
both rgb_color
and hex_color
are in a format acceptable by matplotlib.
with webcolors
html uses RGB tuples with values between 0 and 255.
you can convert between them with the module webcolors, using the functions hex_to_rgb
, rgb_to_hex

- 16,004
- 1
- 22
- 12
A very simplistic approach to convert rgb to hex
>>> rgb = (255, 255, 255)
>>> r, g , b = rgb
>>> hex(r)
'0xff'
>>> hex(r) + hex(g)[2:] + hex(b)[2:]
'0xffffff'
>>>
A simplistic approach to convert Hex to rgb
>>> h = '0xffffff'
>>> h1, h2, h3 = h[0:4], '0x' + h[4:6], '0x' + h[6:8]
>>> h1, h2, h3
('0xff', '0xff', '0xff')
>>> r, g , b = int(h1, 16), int(h2, 16), int(h3, 16)
>>> r, g, b
(255, 255, 255)
Use a module which provides some these facility: webcolors
>>> hex_to_rgb('#000080')
(0, 0, 128)
>>> rgb_to_hex((255, 255, 255))
'#ffffff'
Function doc:
hex_to_rgb(hex_value) Convert a hexadecimal color value to a 3-tuple of integers suitable for use in an rgb() triplet specifying that color.
rgb_to_hex(rgb_triplet) : Convert a 3-tuple of integers, suitable for use in an rgb() color triplet, to a normalized hexadecimal value for that color.

- 65,343
- 15
- 148
- 136
-
1note that the rgb to hex fails if any of the input values are less than 16. e.g., `rgb = (0, 255, 0)` would result in `"#0x0ff0"` – Samie Bencherif May 03 '14 at 19:00
HEX to RGB tuple
>>> tuple(bytes.fromhex('61559a'))
(97, 85, 154)
RGB tuple to HEX
>>> bytes((97, 85, 154)).hex()
'61559a'
No imports needed!
What is this magic?!
Since bytes objects are sequences of integers (akin to a tuple), for a bytes object b, b[0] will be an integer, while b[0:1] will be a bytes object of length 1
...
The representation of bytes objects uses the literal format (b'...') since it is often more useful than e.g. bytes([46, 46, 46]). You can always convert a bytes object into a list of integers using list(b).
Source: https://docs.python.org/3/library/stdtypes.html#bytes-objects

- 3,443
- 1
- 29
- 34
def hex_to_int_color(v):
if v[0] == '#':
v = v[1:]
assert(len(v) == 6)
return int(v[:2], 16), int(v[2:4], 16), int(v[4:6], 16)
def int_to_hex_color(v):
assert(len(v) == 3)
return '#%02x%02x%02x' % v

- 6,261
- 1
- 30
- 41
-
def int_to_hex_color(v): assert(len(v) == 3) return '#%02x%02x%02x' % v – spacedentist Nov 28 '10 at 10:59
-
Sorry, your int_to_hex_color does not return correct results when some of the colour components have values < 16. int_to_hex_color((30,20,10)) -> '#1e14a' – spacedentist Nov 28 '10 at 11:10
import re
def hex_to_int_color(v):
return tuple(int(i,16) for i in re.match(
r'^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$', v,
flags=re.IGNORECASE).groups())
def int_to_hex_color(v):
return '#%02x%02x%02x' % v

- 390
- 1
- 4
Here you go. I use it to convert color to graphviz color format in #RGBA
format with prefix=#
.
def rgba_hex( color, prefix = '0x' ):
if len( color ) == 3:
color = color + (255,)
hexColor = prefix + ''.join( [ '%02x' % x for x in color ] )
return hexColor
USAGE:
In [3]: rgba_hex( (222, 100, 34) )
Out[3]: '0xde6422ff'
In [4]: rgba_hex( (0,255,255) )
Out[4]: '0x00ffffff'
In [5]: rgba_hex( (0,255,255,0) )
Out[5]: '0x00ffff00'

- 5,438
- 9
- 45
- 58