I need to convert (0, 128, 64)
to something like this "#008040"
. I'm not sure what to call the latter, making searching difficult.

- 8,768
- 3
- 31
- 42

- 50,393
- 94
- 205
- 275
-
1See prior SO answer http://stackoverflow.com/questions/214359/converting-hex-to-rgb-and-vice-versa --of the three answers, the one with the most votes includes a stand-along python code snippet to do what i believe you are after. – doug Aug 01 '10 at 04:28
-
3The term you're looking for is Hex Triplet. http://en.wikipedia.org/wiki/Hex_color#Hex_triplet – Mark Ransom Aug 01 '10 at 04:34
-
For a more general question, with much better answers than here: https://stackoverflow.com/a/57197866/624066 – MestreLion Aug 24 '20 at 21:49
17 Answers
Use the format operator %
:
>>> '#%02x%02x%02x' % (0, 128, 64)
'#008040'
Note that it won't check bounds...
>>> '#%02x%02x%02x' % (0, -1, 9999)
'#00-1270f'

- 205,541
- 37
- 345
- 415
-
Is the 2-digit limit really necessary though? As long as the RGB values are in the proper bounds of 0-255, you shouldn't need it. So you could just do `'#%x%x%x' % (r, g, b)` – wordsforthewise Mar 26 '20 at 02:17
-
9Actually now I see that if you have a value of 0, it needs to be padded with another 0. Thus the 02 to make it two digits. – wordsforthewise Mar 26 '20 at 02:20
def clamp(x):
return max(0, min(x, 255))
"#{0:02x}{1:02x}{2:02x}".format(clamp(r), clamp(g), clamp(b))
This uses the preferred method of string formatting, as described in PEP 3101. It also uses min()
and max
to ensure that 0 <= {r,g,b} <= 255
.
Update added the clamp function as suggested below.
Update From the title of the question and the context given, it should be obvious that this expects 3 ints in [0,255] and will always return a color when passed 3 such ints. However, from the comments, this may not be obvious to everyone, so let it be explicitly stated:
Provided three
int
values, this will return a valid hex triplet representing a color. If those values are between [0,255], then it will treat those as RGB values and return the color corresponding to those values.

- 7,841
- 1
- 34
- 34
I have created a full python program for it the following functions can convert rgb to hex and vice versa.
def rgb2hex(r,g,b):
return "#{:02x}{:02x}{:02x}".format(r,g,b)
def hex2rgb(hexcode):
return tuple(map(ord,hexcode[1:].decode('hex')))
You can see the full code and tutorial at the following link : RGB to Hex and Hex to RGB conversion using Python

- 26,737
- 24
- 105
- 146

- 950
- 10
- 17
-
It does not work for decimal value of rgb. Can you suggest me any solution to it ? – Abhils May 08 '19 at 04:40
-
2
This is an old question but for information, I developed a package with some utilities related to colors and colormaps and contains the rgb2hex function you were looking to convert triplet into hexa value (which can be found in many other packages, e.g. matplotlib). It's on pypi
pip install colormap
and then
>>> from colormap import rgb2hex
>>> rgb2hex(0, 128, 64)
'##008040'
Validity of the inputs is checked (values must be between 0 and 255).

- 1,049
- 1
- 8
- 11
-
4I tried to use rgb2hex but got an error "ImportError: No module named easydev.tools". Can you suggest any solution to it ? – Abhils May 08 '19 at 04:32
-
-
I'm truly surprised no one suggested this approach:
For Python 2 and 3:
'#' + ''.join('{:02X}'.format(i) for i in colortuple)
Python 3.6+:
'#' + ''.join(f'{i:02X}' for i in colortuple)
As a function:
def hextriplet(colortuple):
return '#' + ''.join(f'{i:02X}' for i in colortuple)
color = (0, 128, 64)
print(hextriplet(color))
#008040

- 12,698
- 8
- 66
- 57
triplet = (0, 128, 64)
print '#'+''.join(map(chr, triplet)).encode('hex')
or
from struct import pack
print '#'+pack("BBB",*triplet).encode('hex')
python3 is slightly different
from base64 import b16encode
print(b'#'+b16encode(bytes(triplet)))

- 295,403
- 53
- 369
- 502
you can use lambda and f-strings(available in python 3.6+)
rgb2hex = lambda r,g,b: f"#{r:02x}{g:02x}{b:02x}"
hex2rgb = lambda hx: (int(hx[0:2],16),int(hx[2:4],16),int(hx[4:6],16))
usage
rgb2hex(r,g,b) #output = #hexcolor
hex2rgb("#hex") #output = (r,g,b) hexcolor must be in #hex format

- 89
- 1
- 3
-
1Calling lambda's directly is not recommended for a host of reasons. I used them like this on a project that was reviewed and everyone said the same thing, not to call directly. – Mike from PSG Jul 10 '19 at 18:11
In Python 3.6, you can use f-strings to make this cleaner:
rgb = (0,128, 64)
f'#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}'
Of course you can put that into a function, and as a bonus, values get rounded and converted to int:
def rgb2hex(r,g,b):
return f'#{int(round(r)):02x}{int(round(g)):02x}{int(round(b)):02x}'
rgb2hex(*rgb)

- 17,977
- 9
- 97
- 116
Here is a more complete function for handling situations in which you may have RGB values in the range [0,1] or the range [0,255].
def RGBtoHex(vals, rgbtype=1):
"""Converts RGB values in a variety of formats to Hex values.
@param vals An RGB/RGBA tuple
@param rgbtype Valid valus are:
1 - Inputs are in the range 0 to 1
256 - Inputs are in the range 0 to 255
@return A hex string in the form '#RRGGBB' or '#RRGGBBAA'
"""
if len(vals)!=3 and len(vals)!=4:
raise Exception("RGB or RGBA inputs to RGBtoHex must have three or four elements!")
if rgbtype!=1 and rgbtype!=256:
raise Exception("rgbtype must be 1 or 256!")
#Convert from 0-1 RGB/RGBA to 0-255 RGB/RGBA
if rgbtype==1:
vals = [255*x for x in vals]
#Ensure values are rounded integers, convert to hex, and concatenate
return '#' + ''.join(['{:02X}'.format(int(round(x))) for x in vals])
print(RGBtoHex((0.1,0.3, 1)))
print(RGBtoHex((0.8,0.5, 0)))
print(RGBtoHex(( 3, 20,147), rgbtype=256))
print(RGBtoHex(( 3, 20,147,43), rgbtype=256))

- 56,349
- 34
- 180
- 251
Note that this only works with python3.6 and above.
def rgb2hex(color):
"""Converts a list or tuple of color to an RGB string
Args:
color (list|tuple): the list or tuple of integers (e.g. (127, 127, 127))
Returns:
str: the rgb string
"""
return f"#{''.join(f'{hex(c)[2:].upper():0>2}' for c in color)}"
The above is the equivalent of:
def rgb2hex(color):
string = '#'
for value in color:
hex_string = hex(value) # e.g. 0x7f
reduced_hex_string = hex_string[2:] # e.g. 7f
capitalized_hex_string = reduced_hex_string.upper() # e.g. 7F
string += capitalized_hex_string # e.g. #7F7F7F
return string

- 5,008
- 2
- 36
- 55
-
This function rgb2hex, applied to (13,13,12), gives 0xDDC, but the website RGB to HEX gives it as 0x0D0D0C, and this also concurs with the idea tha tthe number should be 13*65536+13*256+12, and 0xDDC is read by Python as 3548. – Lars Ericson May 27 '18 at 01:40
-
CSS Colors are inconsistent. There are 6-digit hex colors, 3-digit hex colors, rgb notation with decimals and percentages, hsl, etc. I've tweaked the formula to always provide 6 digits hex colors, and though I think it may be more consistent, I'm not sure it's more correct. – Brian Bruggeman May 28 '18 at 03:03
You can also use bit wise operators which is pretty efficient, even though I doubt you'd be worried about efficiency with something like this. It's also relatively clean. Note it doesn't clamp or check bounds. This has been supported since at least Python 2.7.17.
hex(r << 16 | g << 8 | b)
And to change it so it starts with a # you can do:
"#" + hex(243 << 16 | 103 << 8 | 67)[2:]

- 31
- 2
-
1This is great, for the exception it does not work if the R or G channels are 0, as the `hex()` function drops leading zero bits. – S3DEV Apr 21 '22 at 07:23
def RGB(red,green,blue): return '#%02x%02x%02x' % (red,green,blue)
background = RGB(0, 128, 64)
I know one-liners in Python aren't necessarily looked upon kindly. But there are times where I can't resist taking advantage of what the Python parser does allow. It's the same answer as Dietrich Epp's solution (the best), but wrapped up in a single line function. So, thank you Dietrich!
I'm using it now with tkinter :-)

- 5,312
- 21
- 39
There is a package called webcolors. https://github.com/ubernostrum/webcolors
It has a method webcolors.rgb_to_hex
>>> import webcolors
>>> webcolors.rgb_to_hex((12,232,23))
'#0ce817'

- 25,512
- 7
- 93
- 64
If typing the formatting string three times seems a bit verbose...
The combination of bit shifts and an f-string will do the job nicely:
# Example setup.
>>> r, g, b = 0, 0, 195
# Create the hex string.
>>> f'#{r << 16 | g << 8 | b:06x}'
'#0000c3'
This also illustrates a method by which 'leading' zero bits are not dropped, if either the red or green channels are zero.

- 8,768
- 3
- 31
- 42
My course task required doing this without using for loops and other stuff, here is my bizarre solution lol.
color1 = int(input())
color2 = int(input())
color3 = int(input())
color1 = hex(color1).upper()
color2 = hex(color2).upper()
color3 = hex(color3).upper()
print('#'+ color1[2:].zfill(2)+color2[2:].zfill(2)+color3[2:].zfill(2))

- 2,620
- 3
- 33
- 61

- 1
- 2
For all simple color conversion, matplotlib provide a module with a buch of function, among which :
- hsv_to_rgb
- rgb_to_hsv
- to_hex
- to_rgb
- to_rgba
You the just have to normalise. In your case :
from matplotlib.colors import to_hex
t = (0, 128, 64)
to_hex(tuple(v/255. for v in t)) # returns '#008040'

- 33
- 7