image-converter
Image Converter
Convert, resize, compress, and optimize images with Python Pillow.
Quick Start
from PIL import Image
import pillow_heif
# Register HEIF/HEIC support
pillow_heif.register_heif_opener()
img = Image.open("input.heic")
img.save("output.jpg", quality=85, optimize=True)
Dependencies
pip install pillow pillow-heif
Format Conversion
Supported Formats
| Format | Read | Write | Notes |
|---|---|---|---|
| JPEG/JPG | Yes | Yes | Lossy, best for photos |
| PNG | Yes | Yes | Lossless, supports transparency |
| WebP | Yes | Yes | Modern web format, excellent compression |
| HEIC/HEIF | Yes | No* | Apple format, requires pillow-heif |
| GIF | Yes | Yes | Animation support |
| TIFF | Yes | Yes | Lossless, large files |
| BMP | Yes | Yes | Uncompressed |
| AVIF | Yes | Yes* | Best compression, requires pillow-avif-plugin |
*Limited support, check library versions
Mode Conversion
# RGBA (with alpha) -> RGB (for JPEG)
if img.mode in ('RGBA', 'LA', 'P'):
img = img.convert('RGB')
# RGB -> Grayscale
gray = img.convert('L')
# Grayscale -> RGB
rgb = gray.convert('RGB')
Resizing & Downscaling
Proportional Resize
# Resize by percentage
scale = 0.5 # 50%
new_size = (int(img.width * scale), int(img.height * scale))
resized = img.resize(new_size, Image.LANCZOS)
# Resize to max dimension (preserve aspect ratio)
max_dim = 1920
ratio = min(max_dim / img.width, max_dim / img.height)
if ratio < 1:
new_size = (int(img.width * ratio), int(img.height * ratio))
resized = img.resize(new_size, Image.LANCZOS)
Thumbnail (in-place, efficient)
img.thumbnail((800, 800), Image.LANCZOS) # Modifies in-place
Resampling Filters
Image.LANCZOS- Best quality, slower (recommended for downscaling)Image.BICUBIC- Good quality, fasterImage.BILINEAR- Medium qualityImage.NEAREST- Fastest, pixelated (good for pixel art)
Compression & Optimization
JPEG Quality
# Quality 1-100 (80-85 is good balance)
img.save("out.jpg", quality=85, optimize=True)
# Progressive JPEG (loads gradually)
img.save("out.jpg", quality=85, optimize=True, progressive=True)
PNG Optimization
# Maximum compression
img.save("out.png", optimize=True, compress_level=9)
# Reduce colors for smaller file (256 colors max)
quantized = img.quantize(colors=256)
quantized.save("out.png", optimize=True)
WebP (best for web)
# Lossy (like JPEG)
img.save("out.webp", quality=85, method=6)
# Lossless (like PNG but smaller)
img.save("out.webp", lossless=True, quality=100)
Batch Processing
See scripts/batch_convert.py for full batch processing with:
- Parallel processing with concurrent.futures
- Progress reporting
- Error handling
- Multiple output formats
Basic Batch Pattern
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def convert_image(path, output_dir, target_format, quality=85):
img = Image.open(path)
if img.mode != 'RGB':
img = img.convert('RGB')
output = output_dir / f"{path.stem}.{target_format}"
img.save(output, quality=quality, optimize=True)
return output
input_dir = Path("./images")
output_dir = Path("./converted")
output_dir.mkdir(exist_ok=True)
files = list(input_dir.glob("*.png"))
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(
lambda f: convert_image(f, output_dir, "jpg"),
files
))
Metadata & EXIF
Strip All Metadata
# Create clean image (removes ALL metadata including ICC profile)
clean = Image.new(img.mode, img.size)
clean.putdata(list(img.getdata()))
clean.save("clean.jpg", quality=85)
Strip EXIF Only (preserve ICC color profile)
icc = img.info.get('icc_profile')
if 'exif' in img.info:
del img.info['exif']
img.save("out.jpg", quality=85, icc_profile=icc)
Handle EXIF Orientation
from PIL import ImageOps
img = ImageOps.exif_transpose(img) # Auto-rotate based on EXIF
Watermarking
from PIL import Image, ImageDraw, ImageFont
def add_watermark(img, text, opacity=128):
watermark = Image.new('RGBA', img.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(watermark)
# Use default font or specify path
try:
font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 36)
except:
font = ImageFont.load_default()
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = img.width - text_width - 20
y = img.height - text_height - 20
draw.text((x, y), text, font=font, fill=(255, 255, 255, opacity))
if img.mode != 'RGBA':
img = img.convert('RGBA')
return Image.alpha_composite(img, watermark)
Common Tasks
HEIC to JPEG (iPhone photos)
import pillow_heif
pillow_heif.register_heif_opener()
img = Image.open("photo.heic")
img = ImageOps.exif_transpose(img) # Fix orientation
if img.mode != 'RGB':
img = img.convert('RGB')
img.save("photo.jpg", quality=85, optimize=True)
Optimize for Web
def optimize_for_web(input_path, output_path, max_width=1920, quality=85):
img = Image.open(input_path)
img = ImageOps.exif_transpose(img)
# Resize if too large
if img.width > max_width:
ratio = max_width / img.width
new_size = (max_width, int(img.height * ratio))
img = img.resize(new_size, Image.LANCZOS)
# Convert mode
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
# Strip metadata
icc = img.info.get('icc_profile')
# Save optimized
img.save(output_path, quality=quality, optimize=True,
progressive=True, icc_profile=icc)
Create Thumbnails
def create_thumbnail(input_path, output_path, size=(300, 300)):
img = Image.open(input_path)
img = ImageOps.exif_transpose(img)
img.thumbnail(size, Image.LANCZOS)
if img.mode != 'RGB':
img = img.convert('RGB')
img.save(output_path, quality=85, optimize=True)
File Size Comparison
| Format | Typical Size | Best For |
|---|---|---|
| JPEG 85% | 100% baseline | Photos |
| WebP 85% | ~30% smaller | Web images |
| PNG | 2-5x larger | Graphics with transparency |
| AVIF 85% | ~50% smaller | Next-gen web |
| HEIC | ~50% smaller | Apple ecosystem |
Scripts
scripts/batch_convert.py- Full-featured batch converter with CLIscripts/optimize_web.py- Web optimization with size targets
More from horace4444/extend-my-claude-code
watermark-removal
Universal watermark removal with ML-based inpainting and automatic detection. Works on ANY watermark type (Google SynthID, Midjourney, DALL-E, stock photos, logos). Four methods: inpaint (ML, best quality), aggressive (fast), crop (fastest), paint (basic). Auto-detects watermark location in any corner. Use when: (1) Removing ANY type of watermark, (2) Google AI/Imagen/Gemini watermarks, (3) Stock photo watermarks, (4) Logo overlays, (5) Cleaning images for production, (6) Batch processing, or (7) User mentions 'watermark', 'remove watermark', 'clean image', 'SynthID'
114ai-api-integrations
Connect applications, scripts, and backend services to AI model APIs (OpenAI, Anthropic Claude, Google Gemini/Vertex AI, xAI Grok), Supabase (PostgreSQL database with vector search), and Clerk (authentication). Use when building AI-powered features that require (1) AI model integration for text generation, translation, embeddings, or image generation, (2) Supabase database operations with pgvector semantic search, (3) Clerk user authentication and session management, (4) Combining AI outputs with database storage, (5) Cost-optimized model selection and prompt engineering, (6) Best practices for production deployments avoiding common anti-patterns.
7skill-creator
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
4web-design-guidelines
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
4google-image-creator
Generate images using Google AI models (Imagen 4 and Gemini). Presents top 3 model options with pricing, generates images via API, tracks token usage and costs. Use when user needs to: (1) Generate images with Google AI, (2) Choose between Google image models, (3) See pricing for Google image generation, (4) Track image generation costs, or (5) Compare Imagen vs Gemini image models. Self-updating with current pricing from https://ai.google.dev/pricing
4vercel-react-best-practices
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
4