[Tutor] PIL's palette

Peter Szinek peter at rt.sk
Thu Jul 14 23:38:08 CEST 2005


DH>I am trying to figure out what a palette actually is, how it works,

I did this VEEEERRRRYYYY long time ago (10+ years) in C-- (it was an 
embellished assembler) so don't kill me if this works other way in 
python/PIL, but as far as i remember, it worked like this:

Your palette is a LookUp Table (LUT) - it is also named like this in 
your prog ('lut') - which is a 768-long list (or as in this case, a list 
of 256 lists, every inner list has 3 elements - so again you have 768 
elements). So 3x256 or 1x768 is just an implementation detail. Let's see 
the 3x256 version:

index |
0     |  [r,g,b]
1     |  [r,g,b]
2     |  [r,g,b]
...   |
...   |
255   |  [r,g,b]

an [r,g,b] list represents a color - i think you already know this - as 
red, green, blue, where 0 <= r,g,b <= 255. (e.g. (255,0,0) is the 
absolute red, (255,255,255) is the absolute white etc.)

Now your picture looks like this:

blah blah

And when it is rendered, PIL looks up the color (hence lookup table) at 
the given index. So the first pixel of the image will be the color held 
at index 8 in the lookup table (or palette).

So basically the palette is the comupter abstraction of a real painter's 
palette - the real painter has x colors on his palette, and says (by 
looking at the palette): ah, i need this intelligent shade of cobalt 
blue. You do the same here - you have a palette (the look up table) and 
say: ah, i need this color - so you put the INDEX of that color into the 
image, and when the computer is 'painting' he looks up the color at that 

DH>and what PIL's "putpalette()" does with a given data set

It creates the palette, i.e. assigns a color to every index

DH> lut = []
DH> for i in range(256):
DH>     lut.extend([255-i, i/2, i])
DH> #    lut.extend([i, i, i])
DH> im.putpalette(lut)
DH> The first example I found had only the lut.extend([255-i, i/2, i])
DH> command, the second had the one below it (which is now commented out).
DH>  I've tried them both, on an image which is black and blue.

DH> The first one (lut.extend([255-i, i/2, i])) gives an image that is red
DH> and red (you can still see the shading between the two objects so you
DH> can kind of see they're both there, but everything's red).
DH> The second, they're both black.

Yep, because the first produces a palette like this:

index |
0     |  [255,127,0]    orange
1     |  [254,127,1]
2     |  [253,126,2]
...   |                 (some kind of purple, magenta, red ...)
...   |
255   |  [0,0,0]        black

So i think the indices in your original blue image point to colors in 
the new palette which are 'red-like', hence the red-red combo.

The second case, [i,i,i] will generate a perfect gryscale palette 
(255,255,255) is white, (0,0,0) is black, (i,i,i) is gray - (below 
(127,127,127) is light gray otherwise dark gray. Hence the black-black 


More information about the Tutor mailing list