Everything else in the library assumes these few ideas. They have not changed since PIL, so this is the one part of the old handbook that needs almost no translation.
An image is made of one or more bands of numbers. A colour photograph has three, red, green and blue. A greyscale image has one. An image with transparency has a fourth, alpha. im.getbands() tells you what they are called, and im.split() hands them to you as separate single band images.
print(im.getbands())
r, g, b = im.split()
The mode says what those bands mean and how big each number is.
| Mode | Bands | Each pixel |
|---|---|---|
1 | One | A single bit, black or white |
L | One | A byte, 0 to 255 |
P | One | A byte, used as an index into a colour table |
RGB | Three | Three bytes |
RGBA | Four | Three bytes plus alpha |
CMYK | Four | Four bytes, for print |
I | One | A 32 bit signed integer |
F | One | A 32 bit float |
Mode is the most common source of confusing errors. The mode viewer shows what each does to a picture.
im.size is a (width, height) tuple in pixels. Note the order: width first, which is the opposite of numpy, where an array of the same picture is indexed rows first.
The origin is the top left corner, x increases to the right and y increases downwards. A box is (left, upper, right, lower), and the right and lower edges are not included, so (0, 0, 100, 100) is exactly 100 by 100 pixels.
In mode P, each pixel is a number from 0 to 255 that means "the colour at this position in the table". The table holds up to 256 actual colours. This is why blurring a palette image is nonsense: you would be averaging table positions, not colours.
im.info is a dictionary of extras the file format supplied: resolution, transparency, animation delays. What is in it depends entirely on the format, and most of it is not carried across when you save in a different one.
When an image is resized, some rule has to decide what the new pixels contain. Pillow offers NEAREST, BOX, BILINEAR, HAMMING, BICUBIC and LANCZOS. The comparison tool shows all four of the common ones on your own picture.
Image.open() reads the header and stops. The pixel data is read when something needs it, which keeps directory scans fast but means a file object has to stay open until then. Call im.load() to force it.