Skill v1.4.0
currentAutomated scan100/100+1 new, ~3 modified
name: image-utils description: Classic image manipulation with Python Pillow - resize, crop, composite, format conversion, watermarks, brightness/contrast adjustments, and web optimization. Use this skill when post-processing AI-generated images, preparing images for web delivery, batch processing image directories, creating responsive image variants, or performing any deterministic pixel-level image operation. Works standalone or alongside bria-ai for post-processing generated images. license: MIT metadata: author: Bria AI version: "1.4.0"
Image Utilities
Pillow-based utilities for deterministic pixel-level image operations. Use for resize, crop, composite, format conversion, watermarks, and other standard image processing tasks.
When to Use This Skill
- Post-processing AI-generated images: Resize, crop, optimize for web after generation
- Format conversion: PNG ↔ JPEG ↔ WEBP with quality control
- Compositing: Overlay images, paste subjects onto backgrounds
- Batch processing: Resize to multiple sizes, add watermarks
- Web optimization: Compress and resize for fast delivery
- Social media preparation: Crop to platform-specific aspect ratios
When NOT to Use This Skill — Use bria-ai Instead
This skill handles deterministic pixel-level operations only. For any generative or AI-powered image work, use the bria-ai skill instead:
- Generating images from text prompts → use
bria-ai - AI background removal or replacement → use
bria-ai - AI image editing (inpainting, object removal/addition) → use
bria-ai - Style transfer or AI-driven visual effects → use
bria-ai - Creating product lifestyle shots with AI → use
bria-ai - Image upscaling with AI super-resolution → use
bria-ai
Rule of thumb: If the task requires creating new visual content or understanding image semantics, use bria-ai. If the task requires transforming existing pixels (resize, crop, format convert, watermark), use this skill.
If bria-ai is not available, install it with:
npx skills add bria-ai/bria-skill
Quick Reference
| Operation | Method | Description | |
|---|---|---|---|
| Loading | load(source) | Load from URL, path, bytes, or base64 | |
load_from_url(url) | Download image from URL | ||
| Saving | save(image, path) | Save with format auto-detection | |
to_bytes(image, format) | Convert to bytes | ||
to_base64(image, format) | Convert to base64 string | ||
| Resizing | resize(image, width, height) | Resize to exact dimensions | |
scale(image, factor) | Scale by factor (0.5 = half) | ||
thumbnail(image, size) | Fit within size, maintain aspect | ||
| Cropping | crop(image, left, top, right, bottom) | Crop to region | |
crop_center(image, width, height) | Crop from center | ||
crop_to_aspect(image, ratio) | Crop to aspect ratio | ||
| Compositing | paste(bg, fg, position) | Overlay at coordinates | |
composite(bg, fg, mask) | Alpha composite | ||
fit_to_canvas(image, w, h) | Fit onto canvas size | ||
| Borders | add_border(image, width, color) | Add solid border | |
add_padding(image, padding) | Add whitespace padding | ||
| Transforms | rotate(image, angle) | Rotate by degrees | |
flip_horizontal(image) | Mirror horizontally | ||
flip_vertical(image) | Flip vertically | ||
| Watermarks | add_text_watermark(image, text) | Add text overlay | |
add_image_watermark(image, logo) | Add logo watermark | ||
| Adjustments | adjust_brightness(image, factor) | Lighten/darken | |
adjust_contrast(image, factor) | Adjust contrast | ||
adjust_saturation(image, factor) | Adjust color saturation | ||
blur(image, radius) | Apply Gaussian blur | ||
| Web | optimize_for_web(image, max_size) | Optimize for delivery | |
| Info | get_info(image) | Get dimensions, format, mode |
Requirements
pip install Pillow requests
Basic Usage
from image_utils import ImageUtils# Load from URLimage = ImageUtils.load_from_url("https://example.com/image.jpg")# Or load from various sourcesimage = ImageUtils.load("/path/to/image.png") # File pathimage = ImageUtils.load(image_bytes) # Bytesimage = ImageUtils.load("data:image/png;base64,...") # Base64# Resize and saveresized = ImageUtils.resize(image, width=800, height=600)ImageUtils.save(resized, "output.webp", quality=90)# Get image infoinfo = ImageUtils.get_info(image)print(f"{info['width']}x{info['height']} {info['mode']}")
Resizing & Scaling
# Resize to exact dimensionsresized = ImageUtils.resize(image, width=800, height=600)# Resize maintaining aspect ratio (fit within bounds)fitted = ImageUtils.resize(image, width=800, height=600, maintain_aspect=True)# Resize by width only (height auto-calculated)resized = ImageUtils.resize(image, width=800)# Scale by factorhalf = ImageUtils.scale(image, 0.5) # 50% sizedouble = ImageUtils.scale(image, 2.0) # 200% size# Create thumbnailthumb = ImageUtils.thumbnail(image, (150, 150))
Cropping
# Crop to specific regioncropped = ImageUtils.crop(image, left=100, top=50, right=500, bottom=350)# Crop from centercenter = ImageUtils.crop_center(image, width=400, height=400)# Crop to aspect ratio (for social media)square = ImageUtils.crop_to_aspect(image, "1:1") # Instagramwide = ImageUtils.crop_to_aspect(image, "16:9") # YouTube thumbnailstory = ImageUtils.crop_to_aspect(image, "9:16") # Stories/Reels# Control crop anchortop_crop = ImageUtils.crop_to_aspect(image, "16:9", anchor="top")bottom_crop = ImageUtils.crop_to_aspect(image, "16:9", anchor="bottom")
Compositing
# Paste foreground onto backgroundresult = ImageUtils.paste(background, foreground, position=(100, 50))# Alpha composite (foreground must have transparency)result = ImageUtils.composite(background, foreground)# Fit image onto canvas with letterboxingcanvas = ImageUtils.fit_to_canvas(image,width=1200,height=800,background_color=(255, 255, 255, 255), # Whiteposition="center" # or "top", "bottom")
Format Conversion
# Convert to different formatspng_bytes = ImageUtils.to_bytes(image, "PNG")jpeg_bytes = ImageUtils.to_bytes(image, "JPEG", quality=85)webp_bytes = ImageUtils.to_bytes(image, "WEBP", quality=90)# Get base64 for data URLsbase64_str = ImageUtils.to_base64(image, "PNG")data_url = ImageUtils.to_base64(image, "PNG", include_data_url=True)# Returns: "data:image/png;base64,..."# Save with format auto-detected from extensionImageUtils.save(image, "output.png")ImageUtils.save(image, "output.jpg", quality=85)ImageUtils.save(image, "output.webp", quality=90)
Watermarks
# Text watermarkwatermarked = ImageUtils.add_text_watermark(image,text="© 2024 My Company",position="bottom-right", # bottom-left, top-right, top-left, centerfont_size=24,color=(255, 255, 255, 128), # Semi-transparent whitemargin=20)# Logo/image watermarklogo = ImageUtils.load("logo.png")watermarked = ImageUtils.add_image_watermark(image,watermark=logo,position="bottom-right",opacity=0.5,scale=0.15, # 15% of image widthmargin=20)
Adjustments
# Brightness (1.0 = original, <1 darker, >1 lighter)bright = ImageUtils.adjust_brightness(image, 1.3)dark = ImageUtils.adjust_brightness(image, 0.7)# Contrast (1.0 = original)high_contrast = ImageUtils.adjust_contrast(image, 1.5)# Saturation (0 = grayscale, 1.0 = original, >1 more vivid)vivid = ImageUtils.adjust_saturation(image, 1.3)grayscale = ImageUtils.adjust_saturation(image, 0)# Sharpnesssharp = ImageUtils.adjust_sharpness(image, 2.0)# Blurblurred = ImageUtils.blur(image, radius=5)
Transforms
# Rotate (counter-clockwise, degrees)rotated = ImageUtils.rotate(image, 45)rotated = ImageUtils.rotate(image, 90, expand=False) # Don't expand canvas# Flipmirrored = ImageUtils.flip_horizontal(image)flipped = ImageUtils.flip_vertical(image)
Borders & Padding
# Add solid borderbordered = ImageUtils.add_border(image, width=5, color=(0, 0, 0))# Add padding (whitespace)padded = ImageUtils.add_padding(image, padding=20) # Uniformpadded = ImageUtils.add_padding(image, padding=(10, 20, 10, 20)) # left, top, right, bottom
Web Optimization
# Optimize for web deliveryoptimized_bytes = ImageUtils.optimize_for_web(image,max_dimension=1920, # Resize if largerformat="WEBP", # Best compressionquality=85)# Save optimizedwith open("optimized.webp", "wb") as f:f.write(optimized_bytes)
Integration with Bria AI
Use alongside the [bria-ai skill](https://clawhub.ai/galbria/bria-ai) to post-process AI-generated images. Generate or edit images with Bria's API, then use image-utils for resizing, cropping, watermarking, and web optimization.
import requestsfrom image_utils import ImageUtils# Generate with Bria AI (see bria-ai skill for full API reference)response = requests.post("https://engine.prod.bria-api.com/v2/image/generate",headers={"api_token": BRIA_API_KEY, "Content-Type": "application/json"},json={"prompt": "product photo of headphones", "aspect_ratio": "1:1", "sync": True})image_url = response.json()["result"]["image_url"]# Download and post-processimage = ImageUtils.load_from_url(image_url)# Create multiple sizes for responsive imagessizes = {"large": ImageUtils.resize(image, width=1200),"medium": ImageUtils.resize(image, width=600),"thumb": ImageUtils.thumbnail(image, (150, 150))}# Save all as optimized WebPfor name, img in sizes.items():ImageUtils.save(img, f"product_{name}.webp", quality=85)
Batch Processing Example
from pathlib import Pathfrom image_utils import ImageUtilsdef process_catalog(input_dir, output_dir):"""Process all images in a directory."""output_path = Path(output_dir)output_path.mkdir(exist_ok=True)for image_file in Path(input_dir).glob("*.{jpg,png,webp}"):image = ImageUtils.load(image_file)# Crop to squaresquare = ImageUtils.crop_to_aspect(image, "1:1")# Resize to standard sizeresized = ImageUtils.resize(square, width=800, height=800)# Add watermarkfinal = ImageUtils.add_text_watermark(resized, "© My Brand")# Save optimizedoutput_file = output_path / f"{image_file.stem}.webp"ImageUtils.save(final, output_file, quality=85)process_catalog("./raw_images", "./processed")
API Reference
See image_utils.py for complete implementation with docstrings.