skills/libvips-image/SKILL.md
High-performance image processing with libvips. Use for resizing, converting, watermarking, thumbnails, and batch image operations with low memory usage.
npx skillsauth add agiseek/agent-skills libvips-imageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fast, memory-efficient image processing using libvips via pyvips. Supports 300+ operations including resize, crop, rotate, convert, watermark, composite, and more. Ideal for batch processing large images.
# Recommended: Auto-detect OS and install everything
./scripts/install.sh
The install script will:
macOS (Homebrew):
brew install vips
uv pip install pyvips # preferred
# or: pip install pyvips
Ubuntu/Debian:
sudo apt-get install libvips-dev
uv pip install pyvips # preferred
# or: pip install pyvips
Fedora/RHEL:
sudo dnf install vips-devel
uv pip install pyvips
Arch Linux:
sudo pacman -S libvips
uv pip install pyvips
Windows (PowerShell, recommended):
# One-click install (downloads libvips + installs pyvips)
.\scripts\install.ps1
Windows (Manual):
# Option 1: winget (if available)
winget install libvips.libvips
# Option 2: scoop
scoop install libvips
# Option 3: Manual download
# Download from https://github.com/libvips/libvips/releases
# Extract to C:\vips or %LOCALAPPDATA%\vips
# Add bin\ to PATH
# Install pyvips
uv pip install pyvips
# or: pip install pyvips
Install uv (if not installed):
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
macOS/Linux - Using run.sh wrapper (recommended):
./scripts/run.sh vips_tool.py resize input.jpg output.jpg --width 800
./scripts/run.sh vips_tool.py convert input.jpg output.webp --quality 85
./scripts/run.sh vips_tool.py thumbnail input.jpg thumb.jpg --size 200
./scripts/run.sh vips_batch.py resize ./input ./output --width 800
Windows - Using run.bat wrapper (recommended):
.\scripts\run.bat vips_tool.py resize input.jpg output.jpg --width 800
.\scripts\run.bat vips_tool.py convert input.jpg output.webp --quality 85
.\scripts\run.bat vips_tool.py thumbnail input.jpg thumb.jpg --size 200
.\scripts\run.bat vips_batch.py resize .\input .\output --width 800
Cross-platform - Using uv (after uv sync):
uv run python scripts/vips_tool.py resize input.jpg output.jpg --width 800
Direct Python (if library paths are configured):
python scripts/vips_tool.py resize input.jpg output.jpg --width 800
python scripts/vips_tool.py convert input.jpg output.webp --quality 85
python scripts/vips_tool.py thumbnail input.jpg thumb.jpg --size 200
python scripts/vips_tool.py watermark input.jpg output.jpg --text "Copyright 2024"
| Format | Read | Write | Notes | |--------|------|-------|-------| | JPEG | Yes | Yes | Quality 1-100 | | PNG | Yes | Yes | Compression 0-9 | | WebP | Yes | Yes | Lossy/lossless | | AVIF | Yes | Yes | Modern, high compression | | HEIC | Yes | Yes | Apple format | | TIFF | Yes | Yes | Multi-page support | | GIF | Yes | Yes | Animated support | | PDF | Yes | Yes | Via poppler | | SVG | Yes | No | Via librsvg | | RAW | Yes | No | Via libraw |
Resize images with various fit modes.
# Resize to exact width, maintain aspect ratio
python scripts/vips_tool.py resize input.jpg output.jpg --width 800
# Resize to exact height
python scripts/vips_tool.py resize input.jpg output.jpg --height 600
# Resize to fit within bounds
python scripts/vips_tool.py resize input.jpg output.jpg --width 800 --height 600
# Resize to cover (fill) dimensions
python scripts/vips_tool.py resize input.jpg output.jpg --width 800 --height 600 --mode cover
# Force exact dimensions (may distort)
python scripts/vips_tool.py resize input.jpg output.jpg --width 800 --height 600 --mode force
Resize modes:
fit (default): Fit within bounds, maintain aspect ratiocover: Cover bounds, crop excessforce: Force exact dimensionsCreate optimized thumbnails with smart cropping.
# Square thumbnail
python scripts/vips_tool.py thumbnail input.jpg thumb.jpg --size 200
# Attention-based smart crop
python scripts/vips_tool.py thumbnail input.jpg thumb.jpg --size 200 --crop attention
# Center crop
python scripts/vips_tool.py thumbnail input.jpg thumb.jpg --size 200 --crop centre
Crop strategies:
none: No cropping, fit within sizecentre: Crop from centerattention: Smart crop focusing on interesting areasentropy: Crop to maximize entropyConvert between image formats with quality control.
# JPEG to WebP
python scripts/vips_tool.py convert input.jpg output.webp --quality 85
# PNG to AVIF (modern format, great compression)
python scripts/vips_tool.py convert input.png output.avif --quality 50
# JPEG to PNG (lossless)
python scripts/vips_tool.py convert input.jpg output.png
# With compression level for PNG
python scripts/vips_tool.py convert input.jpg output.png --compression 9
Extract a region from an image.
# Crop 400x300 region starting at (100, 50)
python scripts/vips_tool.py crop input.jpg output.jpg --left 100 --top 50 --width 400 --height 300
# Smart crop to aspect ratio
python scripts/vips_tool.py crop input.jpg output.jpg --width 800 --height 600 --smart
Rotate images by any angle.
# Rotate 90 degrees clockwise
python scripts/vips_tool.py rotate input.jpg output.jpg --angle 90
# Rotate 45 degrees with background color
python scripts/vips_tool.py rotate input.jpg output.jpg --angle 45 --background "255,255,255"
# Auto-rotate based on EXIF
python scripts/vips_tool.py rotate input.jpg output.jpg --auto
Add text or image watermarks.
# Text watermark
python scripts/vips_tool.py watermark input.jpg output.jpg --text "Copyright 2024"
# Position: top-left, top-right, bottom-left, bottom-right, center
python scripts/vips_tool.py watermark input.jpg output.jpg --text "Logo" --position bottom-right
# With opacity
python scripts/vips_tool.py watermark input.jpg output.jpg --text "Draft" --opacity 0.3
# Image watermark
python scripts/vips_tool.py watermark input.jpg output.jpg --image logo.png --position bottom-right --opacity 0.5
Combine multiple images.
# Overlay image on background
python scripts/vips_tool.py composite background.jpg overlay.png output.jpg
# With position offset
python scripts/vips_tool.py composite background.jpg overlay.png output.jpg --x 100 --y 50
# With blend mode
python scripts/vips_tool.py composite background.jpg overlay.png output.jpg --blend multiply
Blend modes: over, multiply, screen, overlay, darken, lighten
Adjust brightness, contrast, saturation.
# Increase brightness
python scripts/vips_tool.py adjust input.jpg output.jpg --brightness 1.2
# Increase contrast
python scripts/vips_tool.py adjust input.jpg output.jpg --contrast 1.3
# Increase saturation
python scripts/vips_tool.py adjust input.jpg output.jpg --saturation 1.5
# Combine adjustments
python scripts/vips_tool.py adjust input.jpg output.jpg --brightness 1.1 --contrast 1.2 --saturation 1.1
Apply sharpening filter.
# Default sharpen
python scripts/vips_tool.py sharpen input.jpg output.jpg
# Custom sigma (blur radius)
python scripts/vips_tool.py sharpen input.jpg output.jpg --sigma 1.5
# Custom parameters
python scripts/vips_tool.py sharpen input.jpg output.jpg --sigma 1.5 --x1 2 --m2 3
Apply Gaussian blur.
# Default blur
python scripts/vips_tool.py blur input.jpg output.jpg
# Custom sigma
python scripts/vips_tool.py blur input.jpg output.jpg --sigma 5
Flip images horizontally or vertically.
# Horizontal flip (mirror)
python scripts/vips_tool.py flip input.jpg output.jpg --horizontal
# Vertical flip
python scripts/vips_tool.py flip input.jpg output.jpg --vertical
Convert to grayscale.
python scripts/vips_tool.py grayscale input.jpg output.jpg
Get image metadata.
python scripts/vips_tool.py info input.jpg
Output:
File: input.jpg
Format: jpeg
Width: 3840
Height: 2160
Bands: 3
Interpretation: srgb
Size: 2.4 MB
Process multiple images at once.
# Resize all JPEGs in a directory
python scripts/vips_batch.py resize ./input ./output --width 800 --pattern "*.jpg"
# Convert all images to WebP
python scripts/vips_batch.py convert ./input ./output --format webp --quality 85
# Create thumbnails for all images
python scripts/vips_batch.py thumbnail ./input ./thumbnails --size 200
# Custom batch with JSON config
python scripts/vips_batch.py --config batch_config.json
{
"input_dir": "./input",
"output_dir": "./output",
"operations": [
{"type": "resize", "width": 1920},
{"type": "sharpen", "sigma": 0.5},
{"type": "convert", "format": "webp", "quality": 85}
],
"pattern": "*.{jpg,jpeg,png}",
"recursive": true,
"workers": 4
}
import pyvips
# Load image
image = pyvips.Image.new_from_file("input.jpg")
# Resize
resized = image.resize(0.5) # 50% scale
resized = image.thumbnail_image(800) # 800px width
# Save
resized.write_to_file("output.jpg", Q=85) # JPEG quality 85
resized.write_to_file("output.webp", Q=85) # WebP quality 85
import pyvips
# Load, process, save in one pipeline
image = pyvips.Image.new_from_file("input.jpg", access="sequential")
result = (
image
.thumbnail_image(1200)
.sharpen(sigma=0.5)
.write_to_file("output.webp", Q=85)
)
import pyvips
image = pyvips.Image.new_from_file("input.jpg")
# Create text overlay
text = pyvips.Image.text(
"Copyright 2024",
font="sans 24",
rgba=True
)
# Composite at bottom-right
x = image.width - text.width - 20
y = image.height - text.height - 20
result = image.composite2(text, "over", x=x, y=y)
result.write_to_file("output.jpg")
import pyvips
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def process_image(input_path, output_dir, width=800):
image = pyvips.Image.new_from_file(str(input_path), access="sequential")
thumbnail = image.thumbnail_image(width)
output_path = output_dir / f"{input_path.stem}.webp"
thumbnail.write_to_file(str(output_path), Q=85)
return output_path
input_dir = Path("./input")
output_dir = Path("./output")
output_dir.mkdir(exist_ok=True)
files = list(input_dir.glob("*.jpg"))
with ThreadPoolExecutor(max_workers=4) as executor:
results = executor.map(lambda f: process_image(f, output_dir), files)
| Parameter | Description | Default |
|-----------|-------------|---------|
| --width | Target width in pixels | - |
| --height | Target height in pixels | - |
| --size | Thumbnail size (square) | 200 |
| --quality | Output quality (1-100) | 85 |
| --compression | PNG compression (0-9) | 6 |
| --mode | Resize mode: fit, cover, force | fit |
| --crop | Crop strategy | none |
| --angle | Rotation angle in degrees | 0 |
| --sigma | Blur/sharpen radius | 1.0 |
| --opacity | Watermark opacity (0-1) | 0.5 |
| --position | Watermark position | bottom-right |
| --workers | Batch processing threads | 4 |
| --pattern | File glob pattern | . |
| --recursive | Process subdirectories | false |
| Tip | Description |
|-----|-------------|
| Sequential access | Use access="sequential" for streaming |
| Pipeline operations | Chain operations before writing |
| Parallel processing | Use ThreadPoolExecutor for batches |
| Format selection | WebP/AVIF for web, JPEG for photos |
| Quality settings | 85 for quality, 75 for size |
| Thumbnail vs resize | thumbnail_image is faster for downscaling |
libvips uses a streaming architecture:
| Issue | Solution |
|-------|----------|
| "Cannot find libvips" | Install via brew/apt, check PATH |
| Slow processing | Use sequential access, check disk I/O |
| Memory errors | Increase cache, reduce workers |
| Format not supported | Install optional dependencies |
| Poor quality | Increase quality parameter |
| HEIC not working | Install libheif: brew install libheif |
| SVG not rendering | Install librsvg: brew install librsvg |
| Issue | Solution |
|-------|----------|
| "cannot load library 'libvips-42.dll'" | Add vips bin\ folder to PATH |
| DLL not found after install | Restart terminal/PowerShell |
| winget install fails | Use manual download or scoop |
| Permission denied | Run PowerShell as Administrator |
| PATH not updated | Log out and log back in, or restart |
Windows PATH Setup (Manual):
# Add to current session
$env:PATH = "C:\vips\bin;$env:PATH"
# Add permanently (run as Admin or for current user)
[Environment]::SetEnvironmentVariable("PATH", "C:\vips\bin;$env:PATH", "User")
| Issue | Solution |
|-------|----------|
| "cannot load library 'libvips.42.dylib'" | Use ./scripts/run.sh wrapper |
| DYLD_LIBRARY_PATH not working | macOS SIP blocks env vars; use run.sh |
| Homebrew Python issues | Use /opt/homebrew/bin/python3 directly |
macOS Library Path Setup:
# Add to ~/.zshrc or ~/.bashrc
export DYLD_LIBRARY_PATH="/opt/homebrew/lib:$DYLD_LIBRARY_PATH"
| Issue | Solution |
|-------|----------|
| Package not found | Check distro-specific package name |
| ldconfig issues | Run sudo ldconfig after install |
| Permission denied | Use sudo for system packages |
data-ai
Local Qwen3-TTS speech synthesis on Apple Silicon via MLX. Use for offline narration, audiobooks, video voiceovers, and multilingual TTS.
development
Remove visible Gemini AI watermarks from images via reverse alpha blending. Use for cleaning Gemini-generated images, removing the star/sparkle logo watermark, batch watermark removal.
data-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.
data-ai
Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some waiting on outside answers, and others rolling into a later summary.