Pillow-SIMD: A Powerful Image Processing Library
Hello everyone! Today I want to introduce you to an amazing image processing library – Pillow-SIMD. As a Python developer who often deals with images, I can’t get enough of this library. It is the SIMD-accelerated version of Pillow, like installing a “rocket booster” on regular Pillow, making the processing speed astonishingly fast! Whether it’s simple image resizing, cropping, or complex filter effects and image enhancement, Pillow-SIMD can achieve it with outstanding performance. Let’s explore this powerful image processing tool together!
1. Basic Installation and Usage
First, install Pillow-SIMD (make sure to uninstall regular Pillow first):
pip uninstall Pillow
pip install pillow-simd
Basic image operations:
from PIL import Image
import numpy as np
import time
def compare_performance():
"""Compare performance improvement"""
# Load a large image
image = Image.open('large_image.jpg')
# Test resizing operation
start_time = time.time()
for _ in range(100):
resized = image.resize((800, 600))
end_time = time.time()
print(f"Processing 100 resize operations took: {end_time - start_time:.2f} seconds")
# Save test results
resized.save('resized_image.jpg')
compare_performance()
Tip: Pillow-SIMD is usually 4-8 times faster than regular Pillow, especially on CPUs that support AVX2/AVX512!
2. Image Enhancement
Implement various image enhancement effects:
from PIL import Image, ImageEnhance, ImageFilter
import numpy as np
class ImageProcessor:
def __init__(self, image_path):
self.image = Image.open(image_path)
def enhance_image(self, brightness=1.2, contrast=1.2,
sharpness=1.5, color=1.2):
"""Enhance image quality"""
# Increase brightness
enhancer = ImageEnhance.Brightness(self.image)
img = enhancer.enhance(brightness)
# Increase contrast
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(contrast)
# Sharpen
enhancer = ImageEnhance.Sharpness(img)
img = enhancer.enhance(sharpness)
# Adjust color
enhancer = ImageEnhance.Color(img)
img = enhancer.enhance(color)
return img
def apply_filters(self):
"""Apply filter effects"""
# Gaussian blur
blurred = self.image.filter(ImageFilter.GaussianBlur(radius=2))
# Edge enhancement
edge_enhanced = self.image.filter(ImageFilter.EDGE_ENHANCE)
# Emboss effect
embossed = self.image.filter(ImageFilter.EMBOSS)
return {
'blur': blurred,
'edge': edge_enhanced,
'emboss': embossed
}
# Usage example
processor = ImageProcessor('test_image.jpg')
henhanced = processor.enhance_image()
henhanced.save('enhanced.jpg')
filters = processor.apply_filters()
for name, img in filters.items():
img.save(f'{name}_effect.jpg')
3. Batch Processing and Optimization
Efficiently process a large number of images:
import os
from PIL import Image
from concurrent.futures import ThreadPoolExecutor
from functools import partial
class BatchProcessor:
def __init__(self, input_dir, output_dir):
self.input_dir = input_dir
self.output_dir = output_dir
os.makedirs(output_dir, exist_ok=True)
def process_image(self, filename, size=(800, 600)):
"""Process a single image"""
input_path = os.path.join(self.input_dir, filename)
output_path = os.path.join(self.output_dir, filename)
try:
with Image.open(input_path) as img:
# Convert to RGB mode (for PNG and other formats)
if img.mode != 'RGB':
img = img.convert('RGB')
# Resize image
img = img.resize(size, Image.LANCZOS)
# Optimize save
img.save(output_path,
'JPEG',
quality=85,
optimize=True)
return True
except Exception as e:
print(f"Processing {filename} failed: {str(e)}")
return False
def batch_process(self, max_workers=4):
"""Parallel batch process images"""
filenames = [f for f in os.listdir(self.input_dir)
if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
with ThreadPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(self.process_image, filenames))
success = sum(results)
print(f"Successfully processed {success}/{len(filenames)} images")
# Usage example
processor = BatchProcessor('input_images', 'output_images')
processor.batch_process()
4. Image Composition and Watermarking
Create complex image effects:
from PIL import Image, ImageDraw, ImageFont
import numpy as np
class ImageCompositor:
def __init__(self, base_image_path):
self.base_image = Image.open(base_image_path)
def add_watermark(self, text, font_size=40, opacity=0.5):
"""Add a semi-transparent watermark"""
# Create watermark layer
watermark = Image.new('RGBA', self.base_image.size, (0,0,0,0))
draw = ImageDraw.Draw(watermark)
# Load font
font = ImageFont.truetype('arial.ttf', font_size)
# Get text size
text_size = draw.textsize(text, font)
# Calculate position (bottom right corner)
position = (
self.base_image.size[0] - text_size[0] - 20,
self.base_image.size[1] - text_size[1] - 20
)
# Draw watermark
draw.text(
position,
text,
font=font,
fill=(255,255,255,int(255*opacity))
)
# Composite image
return Image.alpha_composite(
self.base_image.convert('RGBA'),
watermark
)
def create_collage(self, images, rows, cols):
"""Create an image collage"""
# Calculate individual image size
w = self.base_image.size[0] // cols
h = self.base_image.size[1] // rows
# Create blank canvas
collage = Image.new('RGB', self.base_image.size)
# Fill images
for idx, img_path in enumerate(images):
if idx >= rows * cols:
break
img = Image.open(img_path)
img = img.resize((w, h), Image.LANCZOS)
x = (idx % cols) * w
y = (idx // cols) * h
collage.paste(img, (x, y))
return collage
# Usage example
compositor = ImageCompositor('background.jpg')
# Add watermark
watermarked = compositor.add_watermark('© 2023 MyPhotos')
watermarked.save('watermarked.png')
# Create collage
image_files = ['img1.jpg', 'img2.jpg', 'img3.jpg', 'img4.jpg']
collage = compositor.create_collage(image_files, 2, 2)
collage.save('collage.jpg')
5. Image Analysis and Processing
Perform image analysis and special effects processing:
from PIL import Image, ImageStat
import numpy as np
class ImageAnalyzer:
def __init__(self, image_path):
self.image = Image.open(image_path)
self.array = np.array(self.image)
def get_dominant_colors(self, num_colors=5):
"""Get dominant colors"""
# Convert to RGB mode
img = self.image.convert('RGB')
# Resize image to speed up processing
img = img.resize((150, 150))
# Convert to numpy array and reshape
pixels = np.float32(img).reshape(-1, 3)
# Use K-means clustering
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=num_colors)
kmeans.fit(pixels)
# Get colors
colors = kmeans.cluster_centers_
return [tuple(map(int, color)) for color in colors]
def auto_adjust(self):
"""Automatically adjust image"""
# Automatic contrast
stat = ImageStat.Stat(self.image)
r,g,b = stat.mean
# Calculate brightness adjustment
brightness = 255 / max(r,g,b)
# Apply adjustment
adjusted = Image.fromarray(
(self.array * brightness).astype(np.uint8)
)
return adjusted
def create_artistic_effect(self, effect_type='sketch'):
"""Create artistic effects"""
if effect_type == 'sketch':
# Create sketch effect
gray = self.image.convert('L')
inv = ImageOps.invert(gray)
blur = inv.filter(ImageFilter.GaussianBlur(radius=2))
return ImageOps.invert(blur)
elif effect_type == 'oil_painting':
# Create oil painting effect
return self.image.filter(ImageFilter.ModeFilter(size=9))
return self.image
# Usage example
analyzer = ImageAnalyzer('test_image.jpg')
# Get dominant colors
colors = analyzer.get_dominant_colors()
print("Dominant colors:", colors)
# Auto adjust
adjusted = analyzer.auto_adjust()
adjusted.save('auto_adjusted.jpg')
# Create artistic effect
sketch = analyzer.create_artistic_effect('sketch')
sketch.save('sketch_effect.jpg')
Exercises
- Create an image batch processing tool that supports resizing and adding watermarks
- Implement an image filter system that includes various artistic effects
- Write an image analysis tool that calculates the dominant colors and statistics of the image
Conclusion
Today we learned the core features of Pillow-SIMD:
- Basic image processing
- Image enhancement techniques
- Batch processing optimization
- Image composition and watermarking
- Image analysis and processing
When using Pillow-SIMD, be aware of:
- Ensure the CPU supports SIMD instruction sets
- Use multithreading wisely
- Pay attention to memory management
- Choose appropriate image save parameters
Pillow-SIMD is a powerful image processing tool that makes image processing both fast and simple. I hope everyone can use this amazing tool in real projects! Remember, good image processing should not only pursue effects but also focus on performance. Let’s create a wonderful world of images with Pillow-SIMD!
