Home / Library / PIL / Handbook / The ImageOps module

The ImageOps module

ImageOps holds the ready made operations that would otherwise be five lines each. All of them return a new image.

The one everybody needs

from PIL import Image, ImageOps

im = ImageOps.exif_transpose(Image.open("photo.jpg"))

Phone cameras do not rotate the pixels when you turn the phone. They record an orientation tag and leave the pixels alone. Browsers and photo apps honour that tag, so the picture looks right, and then your script produces a sideways thumbnail. exif_transpose applies the rotation for real. Put it immediately after every open that handles photographs.

Fitting into a shape

CallWhat you get
contain(im, size)Scaled down to fit inside the box, aspect kept, nothing cropped
cover(im, size)Scaled to fill the box, aspect kept, overflow cropped
fit(im, size, centering=(0.5, 0.5))Exactly the box, cropping whatever does not fit
pad(im, size, color)Exactly the box, with bars added rather than cropping
square = ImageOps.fit(im, (400, 400), Image.Resampling.LANCZOS)

fit is what you want for avatars and grid thumbnails, where every tile has to be the same shape.

Tone

CallWhat it does
autocontrast(im, cutoff=0)Stretches the histogram so the darkest pixel is black and the lightest is white
equalize(im)Flattens the histogram. Strong, and often ugly on photographs
grayscale(im)The same as im.convert("L")
invert(im)A negative
posterize(im, bits)Reduces to a few levels per channel
solarize(im, threshold)Inverts everything above the threshold
colorize(im, black, white)Tints a greyscale image between two colours

autocontrast with a small cutoff, say 1 or 2, is the single most useful one for scanned pages and dull photographs, because the cutoff ignores the few extreme pixels that would otherwise ruin the stretch.

Borders

framed = ImageOps.expand(im, border=10, fill="white")

border can be one number, a pair for left-right and top-bottom, or four numbers.

Related