Image Processing with Pillow

May 30, 2026 | 5 min read

Pixel Loops

from PIL import Image

def grayscale(img: Image.Image) -> Image.Image:
    pixels = img.load()
    for y in range(img.height):
        for x in range(img.width):
            r, g, b = pixels[x, y]
            gray = int(0.299 * r + 0.587 * g + 0.114 * b)
            pixels[x, y] = (gray, gray, gray)
    return img

Image Filters

def invert(img: Image.Image) -> Image.Image:
    pixels = img.load()
    for y in range(img.height):
        for x in range(img.width):
            r, g, b = pixels[x, y]
            pixels[x, y] = (255 - r, 255 - g, 255 - b)
    return img

Performance Notes

Pillow's C extensions handle decoding/encoding. Pyvorin accelerates the Python pixel manipulation loops.