Home / Library / PIL / Handbook / Mode conversions

Mode conversions

What convert() actually does, shown on one picture.

The sample image in RGB mode

RGB

Three bytes a pixel. The normal working mode

The sample image converted to greyscale

convert("L")

One byte a pixel, by luminance weighting

The sample image converted to one bit with dithering

convert("1")

One bit, dithered by default

The sample image converted to one bit without dithering

convert("1", dither=NONE)

A hard threshold at 128

The sample image reduced to sixteen adaptive colours

convert("P", ADAPTIVE, 16)

Sixteen colours chosen from the picture

The sample image reduced to the web palette

convert("P", WEB)

A fixed 216 colour palette. Visibly worse

What each conversion costs

From, toWhat you loseReversible
RGB to LAll colourNo
RGB to PAll but 256 coloursNo
RGBA to RGBTransparency, replaced by black unless you compositeNo
L to RGBNothing, but the file gets three times biggerYes
P to RGBNothingYes, through quantize
RGB to CMYKColours outside the print range, and Pillow's conversion is naiveRoughly
Anything to 1Everything except black and whiteNo

The luminance weighting

L = R * 299/1000 + G * 587/1000 + B * 114/1000

Green counts for more than half because human vision is most sensitive to it. Averaging the three channels instead gives a noticeably flatter, muddier greyscale, which is why hand rolled conversions usually look wrong.

RGBA to RGB, properly

flat = Image.new("RGB", im.size, "white")
flat.paste(im, mask=im.split()[3])

A plain convert("RGB") puts black behind the transparent parts. See cannot write mode RGBA as JPEG.

CMYK

Pillow's RGB to CMYK conversion is a simple formula with no colour profile involved. It is fine for a rough separation and wrong for print work. For that, use ImageCms with real ICC profiles.

Checking what you have

print(im.mode, im.getbands())

Try the conversions on your own picture in the mode viewer, and see concepts for what the modes mean.