Filters are passed to im.filter(), which returns a new image.
from PIL import Image, ImageFilter
im = Image.open("photo.jpg")
soft = im.filter(ImageFilter.GaussianBlur(3))
| Filter | What it does |
|---|---|
GaussianBlur(radius=2) | A proper Gaussian blur. The one to use for blurring |
BoxBlur(radius) | Cheaper, slightly blockier |
UnsharpMask(radius=2, percent=150, threshold=3) | Sharpening. The threshold stops it from sharpening noise |
MedianFilter(size=3) | Replaces each pixel with the median around it. Removes speckle while keeping edges |
MinFilter, MaxFilter | Erode and dilate, useful on masks |
ModeFilter(size) | The most common value nearby. Good on flat colour art |
RankFilter(size, rank) | The general form of the three above |
BLUR, CONTOUR, DETAIL, EDGE_ENHANCE, EDGE_ENHANCE_MORE, EMBOSS, FIND_EDGES, SHARPEN, SMOOTH and SMOOTH_MORE take no arguments and are passed as they are:
edges = im.filter(ImageFilter.FIND_EDGES)
They are small fixed kernels. Handy for a quick effect, but for anything you care about, the adjustable filters give you control over the strength.
Shrinking an image always softens it, because several original pixels are averaged into one. A light unsharp mask afterwards puts the crispness back:
im.thumbnail((1200, 1200), Image.Resampling.LANCZOS)
im = im.filter(ImageFilter.UnsharpMask(radius=1.2, percent=110, threshold=3))
sharpen = ImageFilter.Kernel(
(3, 3),
[0, -1, 0,
-1, 5, -1,
0, -1, 0],
scale=1,
offset=0,
)
im = im.filter(sharpen)
Kernels work on L and RGB images only, and the size must be 3 by 3 or 5 by 5. If scale is left out, Pillow uses the sum of the kernel values, which keeps the overall brightness the same.
Filtering a mode P image filters the palette indexes rather than the colours, which produces nonsense. Convert to RGB first.