Pillow Handbook
Independent practical guide. Canonical source: official Pillow tutorial.
This handbook walks through the everyday Pillow workflow in the order you usually need it: open a file and inspect it, save it in another format, cut out and paste regions, resize and rotate, change colours, and enhance the result. Each section is a short, practical summary with code you can adapt.
Two ideas make the rest easier. First, an Image object is just pixel data plus a mode (how each pixel is stored, such as "RGB" or "L") and a size. Second, almost every operation returns a new image and leaves the original untouched; the main exceptions are thumbnail(), paste() and drawing with ImageDraw, which change the image in place.
from PIL import Image — not import Pillow.
Using the Image Class
The most important class in Pillow is the Image class. You can create instances by loading from files, processing other images, or creating from scratch.
| Attribute | Type | Description |
|---|---|---|
im.format | str | None | Source file format (e.g. 'JPEG', 'PNG'). None for programmatically created images. |
im.mode | str | Pixel format: '1', 'L', 'P', 'RGB', 'RGBA', 'CMYK', 'YCbCr', 'LAB', 'HSV', 'I', 'F' |
im.size | tuple | Image dimensions as (width, height) in pixels. |
im.info | dict | Metadata dictionary populated by the file decoder (DPI, copyright, comments, EXIF). |
im.width | int | Image width in pixels (shortcut for im.size[0]). |
im.height | int | Image height in pixels (shortcut for im.size[1]). |
Reading & Writing Files
Pillow can read and write over 30 image formats. The format is auto-detected on read, and inferred from the file extension on write.
Using StringIO / BytesIO
Cutting, Pasting & Merging
The Image class contains methods to cut out sub-rectangles, paste them back, and merge separate bands into one image.
Geometric Transforms
Pillow supports resizing, rotating, and more complex geometric transforms via the transform() method.
| Method | Signature | Notes |
|---|---|---|
resize() | resize(size, resample=None, box=None, reducing_gap=None) | Returns resized copy. Resample defaults to BICUBIC: NEAREST, BILINEAR, BICUBIC, LANCZOS |
thumbnail() | thumbnail(size, resample=BICUBIC) | Modifies in-place. Preserves aspect ratio. Never upscales. |
crop() | crop(box) | Returns rectangular sub-region. Box: (left, upper, right, lower) |
rotate() | rotate(angle, expand=False, center=None, translate=None) | Counter-clockwise. expand=True grows canvas to fit. |
transpose() | transpose(method) | Flip/rotate. Methods: FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, ROTATE_90/180/270, TRANSPOSE, TRANSVERSE |
transform() | transform(size, method, data, resample) | Affine, perspective, mesh, quad transforms. |
Color Transforms
Pillow can convert between image modes using convert(). It supports dithering when converting from colour to palette mode.
Image Enhancement
The ImageEnhance module provides a standardized API for contrast, brightness, color saturation, and sharpness adjustment. Each class takes an Image and returns an enhancer object; call .enhance(factor) where 1.0 = no change.
Image Sequences (Animations)
Pillow has basic support for image sequences (animation formats like GIF and animated WebP). When you open a sequence file, Pillow automatically loads the first frame.
Creating a GIF
Postscript Printing
Pillow includes a PSDraw module for drawing on Postscript printers. You can set the text font, rotate text, and draw images. This is primarily useful for print pipelines and legacy workflows.
Batch Processing
Pillow is used extensively in batch workflows — converting, resizing, or watermarking large collections of images. Here are the key patterns.