Home / Tools / Colour palette

Colour palette from an image

Median cut, the same algorithm Pillow uses when it quantises an image, applied to whatever you open.

Nothing is uploaded.

How median cut works

Put every pixel in one box. Find the colour axis, red, green or blue, along which that box is widest. Sort by that axis and split the box in half at the middle pixel. Repeat on whichever box holds the most pixels, until you have as many boxes as you want colours. The average of each box is your palette.

The useful property is that it splits where the colours actually are, rather than dividing the colour cube evenly. A photograph that is mostly sky and sand gets most of its palette spent on blues and browns, which is what you want.

Doing it in Pillow

from PIL import Image

im = Image.open("photo.jpg").convert("RGB")
small = im.resize((160, 160))
flat = small.quantize(colors=8, method=Image.Quantize.MEDIANCUT)

table = flat.getpalette()
for n in range(8):
    print(tuple(table[n * 3:n * 3 + 3]))

Resizing first is not laziness, it is the whole trick. A 160 by 160 copy holds the same colour distribution as the full picture and quantises in a fraction of the time.

Counting exact colours instead

For logos and flat art, where you want the actual colours rather than a summary:

colours = im.getcolors(maxcolors=256)
colours.sort(reverse=True)
for count, colour in colours[:8]:
    print(colour, count)

getcolors returns None if the image has more distinct colours than the limit you gave, which is its way of telling you to quantise instead.