103
votes

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

14
See prior SO answer stackoverflow.com/questions/214359/… --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
The term you're looking for is Hex Triplet. en.wikipedia.org/wiki/Hex_color#Hex_triplet - Mark Ransom
For a more general question, with much better answers than here: stackoverflow.com/a/57197866/624066 - MestreLion

14 Answers

217
votes

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'
57
votes
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.

21
votes

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).

18
votes

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

10
votes
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)))
4
votes

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))
4
votes

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

3
votes

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
3
votes

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
2
votes
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 :-)

1
votes

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)
1
votes

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:]
0
votes

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'
0
votes
''.join('%02x'%i for i in input)

can be used for hex conversion from int number