PIL fork · image I/O & processing · the Python imaging workhorse · verified against Pillow 12 (2026)

Pillow cheat sheet

Pillow (the maintained PIL fork) is the standard library for opening, converting, editing and saving images in Python — the layer under most ML data pipelines (a 🌐 datasets Image, a torchvision input, a matplotlib figure). Core object is Image; helpers live in ImageDraw, ImageFilter, ImageOps, ImageEnhance. This sheet targets Pillow 12.x.

open / inspect / save transform (resize/crop/rotate) compose & draw enhance & filter NumPy & frames gotcha most common

Verified 2026-08-24 against the official docs at pillow.readthedocs.io (Pillow 12.x). Import as from PIL import Image. Interops with NumPy via np.array() / Image.fromarray().

Outline

Open → edit → save. Two things to internalize: most methods return a new image (Pillow is mostly immutable-style), and thumbnail() is the exception that edits in place.

Basics

  1. 1 · Open, inspect, save
  2. 2 · Modes & convert

Transform

  1. 3 · Resize, thumbnail, crop
  2. 4 · Rotate, flip, fit

Create

  1. 5 · New, paste, composite
  2. 6 · Draw shapes & text

Adjust

  1. 7 · Filters & enhance

Interop

  1. 8 · NumPy & pixels
  2. 9 · GIFs & multi-frame
  3. 10 · Gotchas
  4. Worth memorizing

Basics

Load a file, look at it, write it back.

1Open, inspect, saveI/O
2Modes & convertcolor spaces

Transform

Geometry — almost all of these return a new image.

3Resize, thumbnail, cropsize
4Rotate, flip, fitorientation

Create & Compose

Blank canvases, pasting, and drawing.

5New, paste, compositecombine images
6Draw shapes & textImageDraw

Adjust

Filters and tone/color adjustments.

7Filters & enhanceappearance

Interop

Bridge to NumPy and handle animations.

8NumPy & pixelsarrays
9GIFs & multi-frameanimation
!Common gotchasread before shipping

Worth memorizing

from PIL import Imagepackage Pillow, import PIL; Image.open is lazy
methods return new imagesassign resize/crop/rotate/filter results; thumbnail & paste mutate
resize vs thumbnailresize = exact size (new img); thumbnail = fit-in-box, in place, keeps aspect
LANCZOS for downscalingImage.Resampling.LANCZOS gives the cleanest shrink
convert("RGB") before JPEGJPEG has no alpha/palette
exif_transpose earlyfix phone-photo orientation before other edits
ImageDraw for boxes/textDraw(img) then rectangle/text; truetype for real fonts
np.array / fromarrayHWC RGB uint8 bridge to NumPy
save_all + append_imageswrite animated GIFs