image-utils — Claude Code skill: image processing and installation
This skill uses Pillow for pixel-level image edits such as resizing, cropping, format conversion, and watermarks. Use it to prepare web assets or process image batches.
npx skills add Bria-AI/bria-skill --skill image-utils -a claude-codeWhat image-utils does
image-utils loads images from files, URLs, bytes, or base64 data. It can resize and crop them, rotate or combine layers, add borders and watermarks, adjust brightness, contrast, and saturation, and save images in another format. It also provides thumbnails and web optimization.
Install the Python packages Pillow and requests with pip install Pillow requests. The operations are deterministic and work on existing pixels. Image generation, AI background removal, and semantic edits belong to the separate bria-ai skill, so image-utils won't perform those tasks.
What it helps with
- resize images for web pages
- crop artwork to a target aspect ratio
- convert PNG files to JPEG or WEBP
- overlay a logo or text watermark
- create several sizes from one image
Example prompts for the agent
- Resize
product.pngto 800 by 600 and save it asproduct.webp. - Crop
cover.jpgto 16:9, keeping the upper part of the frame. - Add a logo watermark to the images in this folder.
How to install image-utils
1Skills CLI (Vercel)
npx skills add Bria-AI/bria-skill --skill image-utils -a claude-code2Manually: put the files in place
~/.claude/skills/image-utils/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/image-utils/
1Skills CLI (Vercel)
npx skills add Bria-AI/bria-skill --skill image-utils -a codex2Manually: put the files in place
.agents/skills/image-utils/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add Bria-AI/bria-skill --skill image-utils -a cursor2Manually: put the files in place
.cursor/skills/image-utils/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install Bria-AI/bria-skill image-utils2Manually: put the files in place
.github/skills/image-utils/SKILL.md1Skills CLI (Vercel)
npx skills add Bria-AI/bria-skill --skill image-utils -a gemini-cli2Platform CLI
gemini skills install https://github.com/Bria-AI/bria-skill --path skills/image-utilsManually: put the files in place
.devin/skills/image-utils/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add Bria-AI/bria-skill --skill image-utils -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about image-utils
How do I install image-utils in Claude Code?
Run npx skills add Bria-AI/bria-skill --skill image-utils -a claude-code. The skill file will be at ~/.claude/skills/image-utils/SKILL.md.
What does image-utils do?
It uses Pillow for standard image edits, including resizing, cropping, format conversion, compositing, watermarks, color adjustments, and web optimization.
Which dependencies does image-utils need?
Install the Python packages Pillow and requests with pip install Pillow requests. The separate bria-ai skill handles image generation and AI-powered edits.
Source text
SKILL.md · MIT
---
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:
```bash
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
```bash
pip install Pillow requests
```
## Basic Usage
```python
from image_utils import ImageUtils
# Load from URL
image = ImageUtils.load_from_url("https://example.com/image.jpg")
# Or load from various sources
image = ImageUtils.load("/path/to/image.png") # File path
image = ImageUtils.load(image_bytes) # Bytes
image = ImageUtils.load("data:image/png;base64,...") # Base64
# Resize and save
resized = ImageUtils.resize(image, width=800, height=600)
ImageUtils.save(resized, "output.webp", quality=90)
# Get image info
info = ImageUtils.get_info(image)
print(f"{info['width']}x{info['height']} {info['mode']}")
```
## Resizing & Scaling
```python
# Resize to exact dimensions
resized = 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 factor
half = ImageUtils.scale(image, 0.5) # 50% size
double = ImageUtils.scale(image, 2.0) # 200% size
# Create thumbnail
thumb = ImageUtils.thumbnail(image, (150, 150))
```
## Cropping
```python
# Crop to specific region
cropped = ImageUtils.crop(image, left=100, top=50, right=500, bottom=350)
# Crop from center
center = ImageUtils.crop_center(image, width=400, height=400)
# Crop to aspect ratio (for social media)
square = ImageUtils.crop_to_aspect(image, "1:1") # Instagram
wide = ImageUtils.crop_to_aspect(image, "16:9") # YouTube thumbnail
story = ImageUtils.crop_to_aspect(image, "9:16") # Stories/Reels
# Control crop anchor
top_crop = ImageUtils.crop_to_aspect(image, "16:9", anchor="top")
bottom_crop = ImageUtils.crop_to_aspect(image, "16:9", anchor="bottom")
```
## Compositing
```python
# Paste foreground onto background
result = ImageUtils.paste(background, foreground, position=(100, 50))
# Alpha composite (foreground must have transparency)
result = ImageUtils.composite(background, foreground)
# Fit image onto canvas with letterboxing
canvas = ImageUtils.fit_to_canvas(
image,
width=1200,
height=800,
background_color=(255, 255, 255, 255), # White
position="center" # or "top", "bottom"
)
```
## Format Conversion
```python
# Convert to different formats
png_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 URLs
base64_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 extension
ImageUtils.save(image, "output.png")
ImageUtils.save(image, "output.jpg", quality=85)
ImageUtils.save(image, "output.webp", quality=90)
```
## Watermarks
```python
# Text watermark
watermarked = ImageUtils.add_text_watermark(
image,
text="© 2024 My Company",
position="bottom-right", # bottom-left, top-right, top-left, center
font_size=24,
color=(255, 255, 255, 128), # Semi-transparent white
margin=20
)
# Logo/image watermark
logo = ImageUtils.load("logo.png")
watermarked = ImageUtils.add_image_watermark(
image,
watermark=logo,
position="bottom-right",
opacity=0.5,
scale=0.15, # 15% of image width
margin=20
)
```
## Adjustments
```python
# 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)
# Sharpness
sharp = ImageUtils.adjust_sharpness(image, 2.0)
# Blur
blurred = ImageUtils.blur(image, radius=5)
```
## Transforms
```python
# Rotate (counter-clockwise, degrees)
rotated = ImageUtils.rotate(image, 45)
rotated = ImageUtils.rotate(image, 90, expand=False) # Don't expand canvas
# Flip
mirrored = ImageUtils.flip_horizontal(image)
flipped = ImageUtils.flip_vertical(image)
```
## Borders & Padding
```python
# Add solid border
bordered = ImageUtils.add_border(image, width=5, color=(0, 0, 0))
# Add padding (whitespace)
padded = ImageUtils.add_padding(image, padding=20) # Uniform
padded = ImageUtils.add_padding(image, padding=(10, 20, 10, 20)) # left, top, right, bottom
```
## Web Optimization
```python
# Optimize for web delivery
optimized_bytes = ImageUtils.optimize_for_web(
image,
max_dimension=1920, # Resize if larger
format="WEBP", # Best compression
quality=85
)
# Save optimized
with 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.
```python
import requests
from 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-process
image = ImageUtils.load_from_url(image_url)
# Create multiple sizes for responsive images
sizes = {
"large": ImageUtils.resize(image, width=1200),
"medium": ImageUtils.resize(image, width=600),
"thumb": ImageUtils.thumbnail(image, (150, 150))
}
# Save all as optimized WebP
for name, img in sizes.items():
ImageUtils.save(img, f"product_{name}.webp", quality=85)
```
## Batch Processing Example
```python
from pathlib import Path
from image_utils import ImageUtils
def 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 square
square = ImageUtils.crop_to_aspect(image, "1:1")
# Resize to standard size
resized = ImageUtils.resize(square, width=800, height=800)
# Add watermark
final = ImageUtils.add_text_watermark(resized, "© My Brand")
# Save optimized
output_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](./references/code-examples/image_utils.py) for complete implementation with docstrings.
© Bria AI · MIT · Bria-AI/bria-skill