Python Imaging Library (Fork) providing comprehensive image processing capabilities for reading, writing, and manipulating images across dozens of formats.
—
Comprehensive filtering system for image enhancement, blur effects, edge detection, and artistic effects. The ImageFilter module provides both built-in filters and the capability to create custom filters for advanced image processing.
Base classes for creating and using image filters.
class Filter:
"""Abstract base class for all image filters."""
class MultibandFilter(Filter):
"""Base class for filters that can be applied to multi-band images."""
class BuiltinFilter(MultibandFilter):
"""Base class for built-in C-implemented filters."""
class Kernel(BuiltinFilter):
"""Convolution kernel filter for custom filtering operations."""
def __init__(self, size, kernel, scale=None, offset=0):
"""
Create a convolution kernel filter.
Parameters:
- size (tuple): Kernel size as (width, height)
- kernel (sequence): Kernel values (length must equal width * height)
- scale (float): Scale factor for kernel values
- offset (int): Offset added to convolution result
"""
class RankFilter(Filter):
"""Base class for rank-based filters that work on pixel neighborhoods."""
def __init__(self, size, rank):
"""
Create a rank filter.
Parameters:
- size (int): Neighborhood size (must be odd)
- rank (int): Rank within neighborhood (0 to size²-1)
"""Various blur and smoothing effects.
class GaussianBlur(MultibandFilter):
"""Gaussian blur filter with configurable radius."""
def __init__(self, radius=2):
"""
Create a Gaussian blur filter.
Parameters:
- radius (float): Blur radius in pixels
"""
class BoxBlur(MultibandFilter):
"""Box blur filter providing uniform averaging."""
def __init__(self, radius):
"""
Create a box blur filter.
Parameters:
- radius (float): Blur radius in pixels
"""
class MotionBlur(BuiltinFilter):
"""Motion blur filter simulating camera or object movement."""
def __init__(self, size, angle):
"""
Create a motion blur filter.
Parameters:
- size (float): Length of blur in pixels
- angle (float): Angle of motion in degrees
"""
# Built-in blur filter instances
BLUR: BuiltinFilter # Standard blur filter
SMOOTH: BuiltinFilter # Light smoothing filter
SMOOTH_MORE: BuiltinFilter # Strong smoothing filterFilters for enhancing image sharpness and detail.
class UnsharpMask(MultibandFilter):
"""Unsharp mask filter for advanced sharpening control."""
def __init__(self, radius=2, percent=150, threshold=3):
"""
Create an unsharp mask filter.
Parameters:
- radius (float): Blur radius for mask creation
- percent (int): Sharpening strength as percentage
- threshold (int): Minimum difference for sharpening to be applied
"""
# Built-in sharpening filter instances
SHARPEN: BuiltinFilter # Standard sharpening filter
DETAIL: BuiltinFilter # Detail enhancement filterFilters for detecting and enhancing edges in images.
# Built-in edge detection filter instances
FIND_EDGES: BuiltinFilter # Edge detection filter
EDGE_ENHANCE: BuiltinFilter # Light edge enhancement
EDGE_ENHANCE_MORE: BuiltinFilter # Strong edge enhancement
CONTOUR: BuiltinFilter # Contour detection filterFilters for creating artistic and stylistic effects.
# Built-in artistic effect filter instances
EMBOSS: BuiltinFilter # Emboss effect filterFilters based on pixel ranking in neighborhoods.
class MedianFilter(RankFilter):
"""Median filter for noise reduction while preserving edges."""
def __init__(self, size=3):
"""
Create a median filter.
Parameters:
- size (int): Filter size (must be odd, typically 3, 5, or 7)
"""
class MinFilter(RankFilter):
"""Minimum filter - selects darkest pixel in neighborhood."""
def __init__(self, size=3):
"""
Create a minimum filter.
Parameters:
- size (int): Filter size (must be odd)
"""
class MaxFilter(RankFilter):
"""Maximum filter - selects brightest pixel in neighborhood."""
def __init__(self, size=3):
"""
Create a maximum filter.
Parameters:
- size (int): Filter size (must be odd)
"""
class ModeFilter(Filter):
"""Mode filter - selects most common pixel value in neighborhood."""
def __init__(self, size=3):
"""
Create a mode filter.
Parameters:
- size (int): Filter size (must be odd)
"""Methods for applying filters to images.
class Image:
def filter(self, filter):
"""
Apply a filter to the image.
Parameters:
- filter (Filter): Filter instance to apply
Returns:
Image: Filtered image
"""from PIL import Image, ImageFilter
# Open an image
img = Image.open("photo.jpg")
# Apply various built-in filters
blurred = img.filter(ImageFilter.BLUR)
sharpened = img.filter(ImageFilter.SHARPEN)
edges = img.filter(ImageFilter.FIND_EDGES)
embossed = img.filter(ImageFilter.EMBOSS)
# Save results
blurred.save("blurred.jpg")
sharpened.save("sharpened.jpg")
edges.save("edges.jpg")
embossed.save("embossed.jpg")from PIL import Image, ImageFilter
img = Image.open("portrait.jpg")
# Different blur techniques
gaussian_light = img.filter(ImageFilter.GaussianBlur(radius=1))
gaussian_heavy = img.filter(ImageFilter.GaussianBlur(radius=5))
box_blur = img.filter(ImageFilter.BoxBlur(radius=3))
# Motion blur for dynamic effect
motion_blur = img.filter(ImageFilter.MotionBlur(size=10, angle=45))
# Save variations
gaussian_light.save("light_blur.jpg")
gaussian_heavy.save("heavy_blur.jpg")
box_blur.save("box_blur.jpg")
motion_blur.save("motion_blur.jpg")from PIL import Image, ImageFilter
# Load a noisy image
noisy_img = Image.open("noisy_photo.jpg")
# Apply median filter to reduce noise while preserving edges
denoised = noisy_img.filter(ImageFilter.MedianFilter(size=3))
# For heavy noise, use larger kernel
heavily_denoised = noisy_img.filter(ImageFilter.MedianFilter(size=5))
# Minimum filter to reduce bright noise
min_filtered = noisy_img.filter(ImageFilter.MinFilter(size=3))
# Maximum filter to reduce dark noise
max_filtered = noisy_img.filter(ImageFilter.MaxFilter(size=3))
denoised.save("denoised.jpg")
heavily_denoised.save("heavily_denoised.jpg")from PIL import Image, ImageFilter
img = Image.open("soft_photo.jpg")
# Basic sharpening
basic_sharp = img.filter(ImageFilter.SHARPEN)
# Advanced unsharp mask for professional results
# Subtle sharpening for portraits
portrait_sharp = img.filter(ImageFilter.UnsharpMask(radius=1, percent=100, threshold=3))
# Strong sharpening for landscapes
landscape_sharp = img.filter(ImageFilter.UnsharpMask(radius=2, percent=200, threshold=2))
# Extreme sharpening for special effects
extreme_sharp = img.filter(ImageFilter.UnsharpMask(radius=3, percent=300, threshold=1))
basic_sharp.save("basic_sharp.jpg")
portrait_sharp.save("portrait_sharp.jpg")
landscape_sharp.save("landscape_sharp.jpg")
extreme_sharp.save("extreme_sharp.jpg")from PIL import Image, ImageFilter
img = Image.open("test_image.jpg")
# Custom edge detection kernel
edge_kernel = ImageFilter.Kernel(
size=(3, 3),
kernel=[-1, -1, -1,
-1, 8, -1,
-1, -1, -1],
scale=1,
offset=0
)
# Custom sharpening kernel
sharpen_kernel = ImageFilter.Kernel(
size=(3, 3),
kernel=[ 0, -1, 0,
-1, 5, -1,
0, -1, 0],
scale=1,
offset=0
)
# Custom blur kernel
blur_kernel = ImageFilter.Kernel(
size=(3, 3),
kernel=[1, 1, 1,
1, 1, 1,
1, 1, 1],
scale=9, # Normalize by sum of kernel values
offset=0
)
# Apply custom kernels
edge_detected = img.filter(edge_kernel)
custom_sharpened = img.filter(sharpen_kernel)
custom_blurred = img.filter(blur_kernel)
edge_detected.save("custom_edges.jpg")
custom_sharpened.save("custom_sharpened.jpg")
custom_blurred.save("custom_blurred.jpg")from PIL import Image, ImageFilter
def enhance_photo(img):
"""Professional photo enhancement pipeline."""
# Step 1: Noise reduction
cleaned = img.filter(ImageFilter.MedianFilter(size=3))
# Step 2: Gentle sharpening
sharpened = cleaned.filter(ImageFilter.UnsharpMask(radius=1.5, percent=120, threshold=3))
# Step 3: Edge enhancement
enhanced = sharpened.filter(ImageFilter.EDGE_ENHANCE)
return enhanced
def artistic_effect(img):
"""Create artistic effect by combining filters."""
# Apply emboss effect
embossed = img.filter(ImageFilter.EMBOSS)
# Slight blur to soften harsh edges
softened = embossed.filter(ImageFilter.GaussianBlur(radius=0.5))
return softened
# Process images
original = Image.open("landscape.jpg")
enhanced = enhance_photo(original)
artistic = artistic_effect(original)
enhanced.save("enhanced_landscape.jpg")
artistic.save("artistic_landscape.jpg")from PIL import Image, ImageFilter
def create_filter_comparison(img, output_path):
"""Create a comparison of different filter strengths."""
width, height = img.size
# Create comparison image (2x3 grid)
comparison = Image.new("RGB", (width * 3, height * 2), "white")
# Original and variations
filters_and_labels = [
(None, "Original"),
(ImageFilter.GaussianBlur(1), "Light Blur"),
(ImageFilter.GaussianBlur(3), "Heavy Blur"),
(ImageFilter.SHARPEN, "Sharpened"),
(ImageFilter.UnsharpMask(radius=2, percent=200, threshold=2), "Unsharp Mask"),
(ImageFilter.FIND_EDGES, "Edge Detection")
]
for i, (filter_obj, label) in enumerate(filters_and_labels):
# Apply filter
if filter_obj is None:
filtered = img
else:
filtered = img.filter(filter_obj)
# Calculate position in grid
col = i % 3
row = i // 3
x = col * width
y = row * height
# Paste filtered image
comparison.paste(filtered, (x, y))
comparison.save(output_path)
# Create comparison
img = Image.open("sample.jpg")
create_filter_comparison(img, "filter_comparison.jpg")from PIL import Image, ImageFilter
# Load images in different modes
rgb_img = Image.open("color_photo.jpg") # RGB mode
grayscale_img = Image.open("bw_photo.jpg").convert("L") # L mode
rgba_img = Image.open("logo.png") # RGBA mode
# Apply filters appropriate for each mode
# RGB - all filters work
rgb_filtered = rgb_img.filter(ImageFilter.GaussianBlur(2))
# Grayscale - efficient for single-channel operations
gray_sharpened = grayscale_img.filter(ImageFilter.SHARPEN)
# RGBA - preserve alpha channel
if rgba_img.mode == "RGBA":
# Split into RGB and alpha
rgb_part = rgba_img.convert("RGB")
alpha_part = rgba_img.split()[-1]
# Apply filter to RGB part only
filtered_rgb = rgb_part.filter(ImageFilter.GaussianBlur(1))
# Recombine with original alpha
filtered_rgba = Image.merge("RGBA", filtered_rgb.split() + [alpha_part])
else:
filtered_rgba = rgba_img.filter(ImageFilter.GaussianBlur(1))
rgb_filtered.save("rgb_filtered.jpg")
gray_sharpened.save("gray_sharpened.jpg")
filtered_rgba.save("rgba_filtered.png")Install with Tessl CLI
npx tessl i tessl/pypi-pillow