Mode is the thing beginners skip and then spend an afternoon debugging. This shows the four you will meet most, on your own image.
Nothing is uploaded. The conversions run in your browser.
| Mode | What it holds | Per pixel | Use it for |
|---|---|---|---|
RGB | Three colour channels | 3 bytes | The normal working mode for colour |
RGBA | Three channels plus alpha | 4 bytes | Transparency, compositing, PNG output |
L | One channel, 0 to 255 | 1 byte | Greyscale, masks, most image processing |
1 | One bit, black or white | 1 bit | Fax, scanning, print separations |
P | An index into a colour table | 1 byte plus the table | GIF, small PNGs, limited colour art |
CMYK | Four print channels | 4 bytes | Print work, and some scanned files |
I and F | 32 bit integers or floats | 4 bytes | Scientific data, depth maps, height fields |
JPEG has no alpha channel, so this raises an error. Convert first, and decide what should show through the transparent parts:
flat = Image.new("RGB", im.size, "white")
flat.paste(im, mask=im.split()[3])
flat.save("out.jpg")
Blurring a P mode image blurs the palette indexes, not the colours, which produces nonsense. Convert to RGB first, filter, then convert back if you need to.
ImageChops and most arithmetic need matching modes. Converting both to L first is usually the right move.
Going to mode 1 applies Floyd and Steinberg dithering by default, which looks like fine noise. For a hard threshold, turn it off and use point:
hard = grey.point(lambda v: 255 if v > 128 else 0).convert("1", dither=Image.Dither.NONE)
The greyscale and dithering here use the same standard methods as Pillow: the usual luminance weighting for L, and Floyd and Steinberg error diffusion for 1. The palette panel shows a fixed six level web palette, which is the simple case; Pillow's adaptive palette picks colours from your image and does better.