Image Processing Examples
This section demonstrates advanced image processing techniques using GUI Image Studio.
Advanced Filtering
Custom Filter Implementation
# Example: Advanced Image Filtering
# Demonstrates how to implement and apply custom image filters.
import gui_image_studio
from PIL import Image, ImageFilter, ImageEnhance
import numpy as np
def apply_vintage_filter(image_path: str, output_path: str) -> bool:
"""
Apply a vintage/retro filter to an image.
Args:
image_path: Path to input image
output_path: Path for output image
Returns:
True if successful
"""
try:
# Load the image
image = gui_image_studio.get_image(image_path)
# Step 1: Reduce saturation for vintage look
enhancer = ImageEnhance.Color(image)
desaturated = enhancer.enhance(0.7) # Reduce saturation by 30%
# Step 2: Apply sepia tint
sepia_tinted = gui_image_studio.apply_tint(desaturated, "#D2B48C", opacity=0.4)
# Step 3: Add slight blur for softness
softened = sepia_tinted.filter(ImageFilter.GaussianBlur(radius=0.5))
# Step 4: Adjust contrast
contrast_enhancer = ImageEnhance.Contrast(softened)
final_image = contrast_enhancer.enhance(1.2) # Increase contrast by 20%
# Save the result
gui_image_studio.save_image(final_image, output_path)
return True
except Exception as e:
print(f"Error applying vintage filter: {e}")
return False
# Example usage
if __name__ == "__main__":
apply_vintage_filter("sample_images/sample_photo.jpg", "vintage_photo.jpg")
Multi-Step Processing Pipeline
# Example: Image Processing Pipeline
# Shows how to create a multi-step processing pipeline for batch operations.
import gui_image_studio
from typing import List, Callable, Any
from PIL import Image
class ImageProcessor:
"""A flexible image processing pipeline."""
def __init__(self):
self.steps: List[Callable] = []
def add_step(self, func: Callable, **kwargs) -> 'ImageProcessor':
"""Add a processing step to the pipeline."""
self.steps.append(lambda img: func(img, **kwargs))
return self
def process(self, image: Image.Image) -> Image.Image:
"""Process image through all pipeline steps."""
result = image
for step in self.steps:
result = step(result)
return result
def process_file(self, input_path: str, output_path: str) -> bool:
"""Process a file through the pipeline."""
try:
image = gui_image_studio.get_image(input_path)
processed = self.process(image)
gui_image_studio.save_image(processed, output_path)
return True
except Exception as e:
print(f"Error processing {input_path}: {e}")
return False
# Define processing functions
def resize_step(image: Image.Image, size: tuple) -> Image.Image:
"""Resize image step."""
return gui_image_studio.resize_image(image, size)
def tint_step(image: Image.Image, color: str, opacity: float = 0.3) -> Image.Image:
"""Apply tint step."""
return gui_image_studio.apply_tint(image, color, opacity)
def enhance_step(image: Image.Image, brightness: float = 1.0,
contrast: float = 1.0) -> Image.Image:
"""Enhance brightness and contrast."""
from PIL import ImageEnhance
if brightness != 1.0:
enhancer = ImageEnhance.Brightness(image)
image = enhancer.enhance(brightness)
if contrast != 1.0:
enhancer = ImageEnhance.Contrast(image)
image = enhancer.enhance(contrast)
return image
# Example pipeline usage
def create_thumbnail_pipeline():
"""Create a pipeline for generating thumbnails."""
return (ImageProcessor()
.add_step(resize_step, size=(150, 150))
.add_step(enhance_step, brightness=1.1, contrast=1.2)
.add_step(tint_step, color="#4ECDC4", opacity=0.1))
def create_web_optimization_pipeline():
"""Create a pipeline for web-optimized images."""
return (ImageProcessor()
.add_step(resize_step, size=(800, 600))
.add_step(enhance_step, contrast=1.1))
# Usage example
if __name__ == "__main__":
# Create thumbnail
thumb_processor = create_thumbnail_pipeline()
thumb_processor.process_file("sample_images/sample_photo.jpg", "thumbnail.jpg")
# Create web-optimized version
web_processor = create_web_optimization_pipeline()
web_processor.process_file("sample_images/sample_photo.jpg", "web_optimized.jpg")
Color Manipulation
Advanced Color Operations
# Example: Advanced Color Manipulation
# Demonstrates sophisticated color manipulation techniques.
import gui_image_studio
from PIL import Image, ImageEnhance
import colorsys
def adjust_hue_saturation_lightness(image_path: str, hue_shift: float = 0,
saturation_factor: float = 1.0,
lightness_factor: float = 1.0) -> Image.Image:
"""
Adjust HSL values of an image.
Args:
image_path: Path to input image
hue_shift: Hue shift in degrees (-180 to 180)
saturation_factor: Saturation multiplier (0.0 to 2.0)
lightness_factor: Lightness multiplier (0.0 to 2.0)
Returns:
Processed PIL Image
"""
image = gui_image_studio.get_image(image_path)
# Convert to RGB if necessary
if image.mode != 'RGB':
image = image.convert('RGB')
# Get pixel data
pixels = image.load()
width, height = image.size
# Process each pixel
for x in range(width):
for y in range(height):
r, g, b = pixels[x, y]
# Convert RGB to HSL
h, l, s = colorsys.rgb_to_hls(r/255.0, g/255.0, b/255.0)
# Apply adjustments
h = (h + hue_shift/360.0) % 1.0 # Normalize hue
s = max(0, min(1, s * saturation_factor)) # Clamp saturation
l = max(0, min(1, l * lightness_factor)) # Clamp lightness
# Convert back to RGB
r, g, b = colorsys.hls_to_rgb(h, l, s)
pixels[x, y] = (int(r*255), int(g*255), int(b*255))
return image
def create_color_variations(image_path: str, output_dir: str = "color_variations"):
"""Create multiple color variations of an image."""
import os
os.makedirs(output_dir, exist_ok=True)
# Original image
original = gui_image_studio.get_image(image_path)
gui_image_studio.save_image(original, f"{output_dir}/original.jpg")
# Hue variations
hue_shifts = [-60, -30, 30, 60, 120, 180]
for shift in hue_shifts:
varied = adjust_hue_saturation_lightness(image_path, hue_shift=shift)
gui_image_studio.save_image(varied, f"{output_dir}/hue_shift_{shift:+d}.jpg")
# Saturation variations
sat_factors = [0.3, 0.6, 1.5, 2.0]
for factor in sat_factors:
varied = adjust_hue_saturation_lightness(image_path, saturation_factor=factor)
gui_image_studio.save_image(varied, f"{output_dir}/saturation_{factor:.1f}.jpg")
# Lightness variations
light_factors = [0.5, 0.7, 1.3, 1.6]
for factor in light_factors:
varied = adjust_hue_saturation_lightness(image_path, lightness_factor=factor)
gui_image_studio.save_image(varied, f"{output_dir}/lightness_{factor:.1f}.jpg")
# Example usage
if __name__ == "__main__":
create_color_variations("sample_images/sample_photo.jpg")
Color Palette Extraction
# Example: Color Palette Extraction
# Extract dominant colors from images and create color palettes.
import gui_image_studio
from PIL import Image
from collections import Counter
import numpy as np
def extract_dominant_colors(image_path: str, num_colors: int = 5) -> list:
"""
Extract dominant colors from an image.
Args:
image_path: Path to input image
num_colors: Number of dominant colors to extract
Returns:
List of RGB tuples representing dominant colors
"""
image = gui_image_studio.get_image(image_path)
# Resize for faster processing
image = image.resize((150, 150))
# Convert to RGB
if image.mode != 'RGB':
image = image.convert('RGB')
# Get all pixels
pixels = list(image.getdata())
# Count color frequency
color_counts = Counter(pixels)
# Get most common colors
dominant_colors = [color for color, count in color_counts.most_common(num_colors)]
return dominant_colors
def create_color_palette_image(colors: list, size: tuple = (400, 100)) -> Image.Image:
"""Create a visual color palette from a list of colors."""
width, height = size
palette = Image.new('RGB', size)
color_width = width // len(colors)
for i, color in enumerate(colors):
# Create rectangle for each color
x1 = i * color_width
x2 = (i + 1) * color_width if i < len(colors) - 1 else width
# Fill the rectangle with the color
for x in range(x1, x2):
for y in range(height):
palette.putpixel((x, y), color)
return palette
def analyze_image_colors(image_path: str, output_dir: str = "color_analysis"):
"""Perform comprehensive color analysis of an image."""
import os
os.makedirs(output_dir, exist_ok=True)
# Extract dominant colors
colors = extract_dominant_colors(image_path, num_colors=8)
# Create palette image
palette = create_color_palette_image(colors)
palette_path = f"{output_dir}/color_palette.png"
gui_image_studio.save_image(palette, palette_path)
# Create tinted versions using dominant colors
original = gui_image_studio.get_image(image_path)
for i, color in enumerate(colors[:5]): # Use top 5 colors
# Convert RGB tuple to hex
hex_color = f"#{color[0]:02x}{color[1]:02x}{color[2]:02x}"
# Apply tint
tinted = gui_image_studio.apply_tint(original, hex_color, opacity=0.3)
tinted_path = f"{output_dir}/tinted_with_color_{i+1}.jpg"
gui_image_studio.save_image(tinted, tinted_path)
# Print color information
print(f"Dominant colors extracted from {image_path}:")
for i, color in enumerate(colors, 1):
hex_color = f"#{color[0]:02x}{color[1]:02x}{color[2]:02x}"
print(f" {i}. RGB{color} -> {hex_color}")
# Example usage
if __name__ == "__main__":
analyze_image_colors("sample_images/sample_photo.jpg")
Geometric Transformations
Advanced Transformation Techniques
# Example: Advanced Geometric Transformations
# Demonstrates complex geometric transformations and perspective effects.
import gui_image_studio
from PIL import Image, ImageDraw
import math
def create_perspective_transform(image_path: str, perspective_factor: float = 0.3) -> Image.Image:
"""
Apply a perspective transformation to create depth effect.
Args:
image_path: Path to input image
perspective_factor: Strength of perspective effect (0.0 to 1.0)
Returns:
Transformed PIL Image
"""
image = gui_image_studio.get_image(image_path)
width, height = image.size
# Calculate perspective transformation points
offset = int(width * perspective_factor)
# Define transformation: trapezoid to rectangle
# Top edge is narrower than bottom edge
transform_points = [
(offset, 0), # Top-left
(width - offset, 0), # Top-right
(width, height), # Bottom-right
(0, height) # Bottom-left
]
# Create new image with perspective
# Note: This is a simplified perspective transform
# For more complex transforms, consider using PIL's transform method
return image # Placeholder - implement actual perspective transform
def create_rotation_sequence(image_path: str, output_dir: str = "rotation_sequence"):
"""Create a sequence of rotated images."""
import os
os.makedirs(output_dir, exist_ok=True)
image = gui_image_studio.get_image(image_path)
# Create rotation sequence
angles = range(0, 360, 15) # Every 15 degrees
for angle in angles:
rotated = gui_image_studio.rotate_image(image, angle)
filename = f"rotation_{angle:03d}deg.png"
output_path = os.path.join(output_dir, filename)
gui_image_studio.save_image(rotated, output_path)
print(f"Created {len(angles)} rotated images in {output_dir}")
def create_scaling_sequence(image_path: str, output_dir: str = "scaling_sequence"):
"""Create a sequence of scaled images."""
import os
os.makedirs(output_dir, exist_ok=True)
image = gui_image_studio.get_image(image_path)
original_size = image.size
# Create scaling sequence
scale_factors = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0]
for factor in scale_factors:
new_size = (int(original_size[0] * factor), int(original_size[1] * factor))
scaled = gui_image_studio.resize_image(image, new_size)
filename = f"scale_{factor:.2f}x.png"
output_path = os.path.join(output_dir, filename)
gui_image_studio.save_image(scaled, output_path)
print(f"Created {len(scale_factors)} scaled images in {output_dir}")
# Example usage
if __name__ == "__main__":
create_rotation_sequence("sample_images/sample_icon.png")
create_scaling_sequence("sample_images/sample_icon.png")
Performance Optimization
Optimized Batch Processing
# Example: Optimized Batch Processing
# Demonstrates efficient techniques for processing large numbers of images.
import gui_image_studio
import os
import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from typing import List, Callable
def process_single_image(args: tuple) -> bool:
"""Process a single image (for use with multiprocessing)."""
input_path, output_path, operations = args
try:
# Load image
image = gui_image_studio.get_image(input_path)
# Apply operations
for operation, params in operations:
if operation == 'resize':
image = gui_image_studio.resize_image(image, params['size'])
elif operation == 'tint':
image = gui_image_studio.apply_tint(image, params['color'])
elif operation == 'rotate':
image = gui_image_studio.rotate_image(image, params['angle'])
# Save result
gui_image_studio.save_image(image, output_path)
return True
except Exception as e:
print(f"Error processing {input_path}: {e}")
return False
def batch_process_threaded(input_files: List[str], output_dir: str,
operations: List[tuple], max_workers: int = 4) -> int:
"""
Process images using threading for I/O-bound operations.
Args:
input_files: List of input file paths
output_dir: Output directory
operations: List of (operation_name, parameters) tuples
max_workers: Maximum number of worker threads
Returns:
Number of successfully processed images
"""
os.makedirs(output_dir, exist_ok=True)
# Prepare arguments for each image
args_list = []
for input_path in input_files:
filename = os.path.basename(input_path)
name, ext = os.path.splitext(filename)
output_path = os.path.join(output_dir, f"{name}_processed{ext}")
args_list.append((input_path, output_path, operations))
# Process with thread pool
successful = 0
with ThreadPoolExecutor(max_workers=max_workers) as executor:
results = executor.map(process_single_image, args_list)
successful = sum(results)
return successful
def batch_process_multiprocess(input_files: List[str], output_dir: str,
operations: List[tuple], max_workers: int = None) -> int:
"""
Process images using multiprocessing for CPU-bound operations.
Args:
input_files: List of input file paths
output_dir: Output directory
operations: List of (operation_name, parameters) tuples
max_workers: Maximum number of worker processes
Returns:
Number of successfully processed images
"""
if max_workers is None:
max_workers = os.cpu_count()
os.makedirs(output_dir, exist_ok=True)
# Prepare arguments for each image
args_list = []
for input_path in input_files:
filename = os.path.basename(input_path)
name, ext = os.path.splitext(filename)
output_path = os.path.join(output_dir, f"{name}_processed{ext}")
args_list.append((input_path, output_path, operations))
# Process with process pool
successful = 0
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = executor.map(process_single_image, args_list)
successful = sum(results)
return successful
def benchmark_processing_methods(input_files: List[str]):
"""Benchmark different processing methods."""
operations = [
('resize', {'size': (400, 300)}),
('tint', {'color': '#FF6B6B'})
]
print(f"Benchmarking with {len(input_files)} images...")
# Sequential processing
start_time = time.time()
sequential_success = 0
for input_path in input_files:
filename = os.path.basename(input_path)
name, ext = os.path.splitext(filename)
output_path = f"sequential_{name}_processed{ext}"
if process_single_image((input_path, output_path, operations)):
sequential_success += 1
sequential_time = time.time() - start_time
# Threaded processing
start_time = time.time()
threaded_success = batch_process_threaded(input_files, "threaded_output", operations)
threaded_time = time.time() - start_time
# Multiprocess processing
start_time = time.time()
multiprocess_success = batch_process_multiprocess(input_files, "multiprocess_output", operations)
multiprocess_time = time.time() - start_time
# Print results
print("\nBenchmark Results:")
print(f"Sequential: {sequential_success}/{len(input_files)} images in {sequential_time:.2f}s")
print(f"Threaded: {threaded_success}/{len(input_files)} images in {threaded_time:.2f}s")
print(f"Multiprocess: {multiprocess_success}/{len(input_files)} images in {multiprocess_time:.2f}s")
if sequential_time > 0:
print(f"\nSpeedup:")
print(f"Threaded: {sequential_time/threaded_time:.2f}x")
print(f"Multiprocess: {sequential_time/multiprocess_time:.2f}x")
# Example usage
if __name__ == "__main__":
# Create test images first
from gui_image_studio.sample_creator import SampleCreator
creator = SampleCreator("benchmark_input", count=10)
creator.create_photo_samples()
# Get list of test images
input_files = [f"benchmark_input/sample_photo_{i:03d}.jpg" for i in range(1, 11)]
input_files = [f for f in input_files if os.path.exists(f)]
# Run benchmark
benchmark_processing_methods(input_files)
Running the Examples
To run these image processing examples:
Create sample images:
gui-image-studio-create-samples
Run individual examples:
python vintage_filter.py python color_analysis.py python batch_processing.py
Check output directories for processed images
Each example demonstrates different aspects of image processing and can be adapted for your specific needs.
Next Steps
After mastering these image processing techniques:
Explore animation_creation for working with animated content
Learn about custom_filters for creating your own processing algorithms
Check out batch_processing for automating large-scale operations
Try gui_application for building interactive image editors