Welcome, guest | Sign In | My Account | Store | Cart

You have colors in a number of formats (html-style #RRGGBB, rgb-tuples (r, g, b), and PIL-style integers). You want to convert between formats. It's pretty easy to do, but also pretty easy to forget; hence, this recipe.

Just for kicks, we'll extract an RGB tuple from an image file at the end.

Python, 65 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def RGBToHTMLColor(rgb_tuple):
    """ convert an (R, G, B) tuple to #RRGGBB """
    hexcolor = '#%02x%02x%02x' % rgb_tuple
    # that's it! '%02x' means zero-padded, 2-digit hex values
    return hexcolor

def HTMLColorToRGB(colorstring):
    """ convert #RRGGBB to an (R, G, B) tuple """
    colorstring = colorstring.strip()
    if colorstring[0] == '#': colorstring = colorstring[1:]
    if len(colorstring) != 6:
        raise ValueError, "input #%s is not in #RRGGBB format" % colorstring
    r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
    r, g, b = [int(n, 16) for n in (r, g, b)]
    return (r, g, b)

def HTMLColorToPILColor(colorstring):
    """ converts #RRGGBB to PIL-compatible integers"""
    colorstring = colorstring.strip()
    while colorstring[0] == '#': colorstring = colorstring[1:]
    # get bytes in reverse order to deal with PIL quirk
    colorstring = colorstring[-2:] + colorstring[2:4] + colorstring[:2]
    # finally, make it numeric
    color = int(colorstring, 16)
    return color

def PILColorToRGB(pil_color):
    """ convert a PIL-compatible integer into an (r, g, b) tuple """
    hexstr = '%06x' % pil_color
    # reverse byte order
    r, g, b = hexstr[4:], hexstr[2:4], hexstr[:2]
    r, g, b = [int(n, 16) for n in (r, g, b)]
    return (r, g, b)

def PILColorToHTMLColor(pil_integer):
    return RGBToHTMLColor(PILColorToRGB(pil_integer))

def RGBToPILColor(rgb_tuple):
    return HTMLColorToPILColor(RGBToHTMLColor(rgb_tuple))

import Image
def getRGBTupleFromImg(file_obj, coords=(0,0)):
    """ 
    Extract an #RRGGBB color string from given pixel coordinates
    in the given file-like object.
    """
    pil_img = Image.open(file_obj)
    pil_img = pil_img.convert('RGB')
    rgb = pil_img.getpixel(coords)
    return rgb

if __name__ == '__main__':
    htmlcolor = '#ff00cc'
    pilcolor = HTMLColorToPILColor(htmlcolor)
    rgb = HTMLColorToRGB(htmlcolor)
    print pilcolor
    print htmlcolor
    print rgb
    print PILColorToHTMLColor(pilcolor)
    print PILColorToRGB(pilcolor)
    print RGBToPILColor(rgb)
    print RGBToHTMLColor(rgb)
    print
    img = open('/tmp/bkg.gif', 'r')
    print getRGBTupleFromImg(img, (0,0))

In C, I probably would have done some bit-shifting and masking. Of course you could do that in python, but I've been shielded from bit-twiddling so long, I found it easier to use hex strings :-)

Note that PIL integer colors have red as the least-significant byte, not the most.

2 comments

Open Geek 18 years, 7 months ago  # | flag

Python color stuff. If you're looking to convert colorspaces, there is a python builtin module colorsys that does that stuff: http://aspn.activestate.com/ASPN/docs/ActivePython/2.4/python/lib/module-colorsys.html

Also, there is a recipe for RGB to hex/HTML colors: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/266466

Paul Winkler (author) 17 years, 5 months ago  # | flag

thanks. I didn't know about the colorsys module, useful for converting between the various tuple color models.

Your other recipe link points to this page :-)

Created by Paul Winkler on Thu, 22 Jan 2004 (PSF)
Python recipes (4591)
Paul Winkler's recipes (2)

Required Modules

Other Information and Tasks