Files
2025-11-30 08:48:52 +08:00

613 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ImageMagick Batch Processing
Complete guide to batch operations, mogrify command, parallel processing, and automation.
## Mogrify Command
### Basic Mogrify
Modify files in-place (overwrites originals).
```bash
# Resize all JPEGs
mogrify -resize 800x600 *.jpg
# Convert format (creates new files)
mogrify -format png *.jpg
# Apply effect to all images
mogrify -quality 85 -strip *.jpg
```
**Warning:** mogrify modifies files in-place. Always backup originals or use `-path` to output to different directory.
### Output to Different Directory
Preserve originals.
```bash
# Create output directory first
mkdir output
# Process to output directory
mogrify -path ./output -resize 800x600 *.jpg
# With format conversion
mogrify -path ./optimized -format webp -quality 80 *.png
```
## Common Batch Operations
### Resize All Images
```bash
# Resize to width 800
mogrify -resize 800x *.jpg
# Resize to height 600
mogrify -resize x600 *.jpg
# Fit within 800×600
mogrify -resize 800x600 *.jpg
# Resize to exact dimensions
mogrify -resize 800x600! *.jpg
# Only shrink, never enlarge
mogrify -resize 800x600\> *.jpg
```
### Format Conversion
```bash
# PNG to JPEG
mogrify -path ./jpg -format jpg -quality 85 *.png
# JPEG to WebP
mogrify -path ./webp -format webp -quality 80 *.jpg
# Any format to PNG
mogrify -path ./png -format png *.{jpg,gif,bmp}
```
### Optimize Images
```bash
# Strip metadata from all JPEGs
mogrify -strip *.jpg
# Optimize JPEGs for web
mogrify -quality 85 -strip -interlace Plane *.jpg
# Compress PNGs
mogrify -quality 95 *.png
# Combined optimization
mogrify -quality 85 -strip -interlace Plane -sampling-factor 4:2:0 *.jpg
```
### Apply Effects
```bash
# Add watermark to all images
mogrify -gravity southeast -draw "image over 10,10 0,0 'watermark.png'" *.jpg
# Convert all to grayscale
mogrify -colorspace Gray *.jpg
# Apply sepia tone
mogrify -sepia-tone 80% *.jpg
# Sharpen all images
mogrify -sharpen 0x1 *.jpg
```
### Thumbnail Generation
```bash
# Create square thumbnails
mogrify -path ./thumbnails -resize 200x200^ -gravity center -extent 200x200 *.jpg
# Create thumbnails with max dimension
mogrify -path ./thumbs -thumbnail 300x300 *.jpg
# Thumbnails with quality control
mogrify -path ./thumbs -thumbnail 200x200 -quality 80 -strip *.jpg
```
## Shell Loops
### Basic For Loop
More control than mogrify.
```bash
# Resize with custom naming
for img in *.jpg; do
magick "$img" -resize 800x600 "resized_$img"
done
# Process to subdirectory
mkdir processed
for img in *.jpg; do
magick "$img" -resize 1920x1080 "processed/$img"
done
```
### Multiple Operations
```bash
# Complex processing pipeline
for img in *.jpg; do
magick "$img" \
-resize 1920x1080^ \
-gravity center \
-crop 1920x1080+0+0 +repage \
-unsharp 0x1 \
-quality 85 -strip \
"processed_$img"
done
```
### Format Conversion with Rename
```bash
# Convert PNG to JPEG with new names
for img in *.png; do
magick "$img" -quality 90 "${img%.png}.jpg"
done
# Add prefix during conversion
for img in *.jpg; do
magick "$img" -resize 800x "web_${img}"
done
```
### Conditional Processing
```bash
# Only process large images
for img in *.jpg; do
width=$(identify -format "%w" "$img")
if [ $width -gt 2000 ]; then
magick "$img" -resize 2000x "resized_$img"
fi
done
# Skip existing output files
for img in *.jpg; do
output="output_$img"
if [ ! -f "$output" ]; then
magick "$img" -resize 800x "$output"
fi
done
```
## Parallel Processing
### GNU Parallel
Process multiple images simultaneously.
```bash
# Install GNU Parallel
# Ubuntu/Debian: sudo apt-get install parallel
# macOS: brew install parallel
# Basic parallel resize
parallel magick {} -resize 800x600 resized_{} ::: *.jpg
# Parallel with function
resize_image() {
magick "$1" -resize 1920x1080 -quality 85 "processed_$1"
}
export -f resize_image
parallel resize_image ::: *.jpg
# Limit concurrent jobs
parallel -j 4 magick {} -resize 800x {} ::: *.jpg
# Progress indicator
parallel --progress magick {} -resize 800x {} ::: *.jpg
```
### Xargs Parallel
```bash
# Using xargs for parallel processing
ls *.jpg | xargs -I {} -P 4 magick {} -resize 800x processed_{}
# With find
find . -name "*.jpg" -print0 | \
xargs -0 -I {} -P 4 magick {} -resize 800x {}
```
## Advanced Batch Patterns
### Recursive Processing
```bash
# Process all JPEGs in subdirectories
find . -name "*.jpg" -exec magick {} -resize 800x {} \;
# With output directory structure
find . -name "*.jpg" -type f | while read img; do
outdir="output/$(dirname "$img")"
mkdir -p "$outdir"
magick "$img" -resize 800x "$outdir/$(basename "$img")"
done
```
### Batch with Different Sizes
```bash
# Generate multiple sizes
for size in 320 640 1024 1920; do
mkdir -p "output/${size}w"
for img in *.jpg; do
magick "$img" -resize ${size}x -quality 85 "output/${size}w/$img"
done
done
# Parallel version
for size in 320 640 1024 1920; do
mkdir -p "output/${size}w"
parallel magick {} -resize ${size}x -quality 85 "output/${size}w/{}" ::: *.jpg
done
```
### Responsive Image Set
```bash
# Create responsive image set with srcset
mkdir -p responsive
for img in *.jpg; do
base="${img%.jpg}"
for width in 320 640 1024 1920; do
magick "$img" -resize ${width}x -quality 85 \
"responsive/${base}-${width}w.jpg"
done
done
```
### Watermark Batch
```bash
# Add watermark to all images
for img in *.jpg; do
magick "$img" watermark.png \
-gravity southeast -geometry +10+10 \
-composite "watermarked_$img"
done
# Different watermark positions for portrait vs landscape
for img in *.jpg; do
width=$(identify -format "%w" "$img")
height=$(identify -format "%h" "$img")
if [ $width -gt $height ]; then
# Landscape
magick "$img" watermark.png -gravity southeast -composite "marked_$img"
else
# Portrait
magick "$img" watermark.png -gravity south -composite "marked_$img"
fi
done
```
## Error Handling
### Check Before Processing
```bash
# Verify image before processing
for img in *.jpg; do
if identify "$img" > /dev/null 2>&1; then
magick "$img" -resize 800x "processed_$img"
else
echo "Skipping corrupt image: $img"
fi
done
```
### Log Processing
```bash
# Log successful and failed operations
log_file="batch_process.log"
error_log="errors.log"
for img in *.jpg; do
if magick "$img" -resize 800x "output/$img" 2>> "$error_log"; then
echo "$(date): Processed $img" >> "$log_file"
else
echo "$(date): Failed $img" >> "$error_log"
fi
done
```
### Dry Run Mode
```bash
# Test without modifying files
dry_run=true
for img in *.jpg; do
cmd="magick $img -resize 800x processed_$img"
if [ "$dry_run" = true ]; then
echo "Would run: $cmd"
else
eval $cmd
fi
done
```
## Optimization Workflows
### Web Publishing Pipeline
```bash
# Complete web optimization workflow
mkdir -p web/{original,optimized,thumbnails}
# Copy originals
cp *.jpg web/original/
# Create optimized versions
mogrify -path web/optimized \
-resize 1920x1080\> \
-quality 85 \
-strip \
-interlace Plane \
web/original/*.jpg
# Create thumbnails
mogrify -path web/thumbnails \
-thumbnail 300x300 \
-quality 80 \
-strip \
web/original/*.jpg
```
### Archive to Web Conversion
```bash
# Convert high-res archives to web formats
for img in archives/*.jpg; do
base=$(basename "$img" .jpg)
# Full size web version
magick "$img" -resize 2048x2048\> -quality 90 -strip "web/${base}.jpg"
# Thumbnail
magick "$img" -thumbnail 400x400 -quality 85 "web/${base}_thumb.jpg"
# WebP version
magick "$img" -resize 2048x2048\> -quality 85 "web/${base}.webp"
done
```
### Print to Web Workflow
```bash
# Convert print-ready images to web
for img in print/*.tif; do
base=$(basename "$img" .tif)
# Convert colorspace and optimize
magick "$img" \
-colorspace sRGB \
-resize 2000x2000\> \
-quality 90 \
-strip \
-interlace Plane \
"web/${base}.jpg"
done
```
## Batch Reporting
### Generate Report
```bash
# Create processing report
report="batch_report.txt"
echo "Batch Processing Report - $(date)" > "$report"
echo "================================" >> "$report"
total=0
success=0
failed=0
for img in *.jpg; do
((total++))
if magick "$img" -resize 800x "output/$img" 2>/dev/null; then
((success++))
echo "$img" >> "$report"
else
((failed++))
echo "$img" >> "$report"
fi
done
echo "" >> "$report"
echo "Total: $total, Success: $success, Failed: $failed" >> "$report"
```
### Image Inventory
```bash
# Create inventory of images
inventory="image_inventory.csv"
echo "Filename,Width,Height,Format,Size,ColorSpace" > "$inventory"
for img in *.{jpg,png,gif}; do
[ -f "$img" ] || continue
info=$(identify -format "%f,%w,%h,%m,%b,%[colorspace]" "$img")
echo "$info" >> "$inventory"
done
```
## Performance Tips
### Optimize Loop Performance
```bash
# Bad: Launch mogrify for each file
for img in *.jpg; do
mogrify -resize 800x "$img"
done
# Good: Process all files in one mogrify call
mogrify -resize 800x *.jpg
# Best: Use parallel processing for complex operations
parallel magick {} -resize 800x -quality 85 processed_{} ::: *.jpg
```
### Memory Management
```bash
# Limit memory for batch processing
for img in *.jpg; do
magick -limit memory 2GB -limit map 4GB \
"$img" -resize 50% "output/$img"
done
```
### Progress Tracking
```bash
# Show progress for long batch operations
total=$(ls *.jpg | wc -l)
current=0
for img in *.jpg; do
((current++))
echo "Processing $current/$total: $img"
magick "$img" -resize 800x "output/$img"
done
```
## Automation Scripts
### Complete Bash Script
```bash
#!/bin/bash
# Configuration
INPUT_DIR="./input"
OUTPUT_DIR="./output"
QUALITY=85
MAX_WIDTH=1920
THUMBNAIL_SIZE=300
# Create output directories
mkdir -p "$OUTPUT_DIR"/{full,thumbnails}
# Process images
echo "Processing images..."
for img in "$INPUT_DIR"/*.{jpg,jpeg,png}; do
[ -f "$img" ] || continue
filename=$(basename "$img")
base="${filename%.*}"
# Full size
magick "$img" \
-resize ${MAX_WIDTH}x\> \
-quality $QUALITY \
-strip \
"$OUTPUT_DIR/full/${base}.jpg"
# Thumbnail
magick "$img" \
-thumbnail ${THUMBNAIL_SIZE}x${THUMBNAIL_SIZE} \
-quality 80 \
-strip \
"$OUTPUT_DIR/thumbnails/${base}_thumb.jpg"
echo "$filename"
done
echo "Done!"
```
### Python Batch Script
```python
#!/usr/bin/env python3
import os
import subprocess
from pathlib import Path
INPUT_DIR = Path("./input")
OUTPUT_DIR = Path("./output")
SIZES = [320, 640, 1024, 1920]
# Create output directories
for size in SIZES:
(OUTPUT_DIR / f"{size}w").mkdir(parents=True, exist_ok=True)
# Process images
for img in INPUT_DIR.glob("*.jpg"):
for size in SIZES:
output = OUTPUT_DIR / f"{size}w" / img.name
subprocess.run([
"magick", str(img),
"-resize", f"{size}x",
"-quality", "85",
"-strip",
str(output)
])
print(f"{img.name} -> {size}w")
```
## Common Batch Recipes
### Social Media Sizes
```bash
# Generate social media image sizes
for img in *.jpg; do
base="${img%.jpg}"
# Instagram square (1080×1080)
magick "$img" -resize 1080x1080^ -gravity center -extent 1080x1080 "${base}_ig_square.jpg"
# Instagram portrait (1080×1350)
magick "$img" -resize 1080x1350^ -gravity center -extent 1080x1350 "${base}_ig_portrait.jpg"
# Facebook post (1200×630)
magick "$img" -resize 1200x630^ -gravity center -extent 1200x630 "${base}_fb_post.jpg"
# Twitter post (1200×675)
magick "$img" -resize 1200x675^ -gravity center -extent 1200x675 "${base}_tw_post.jpg"
done
```
### Email Newsletter Images
```bash
# Optimize images for email
mogrify -path ./email \
-resize 600x\> \
-quality 75 \
-strip \
-interlace Plane \
*.jpg
```
### Backup and Archive
```bash
# Create web versions and keep originals
mkdir -p {originals,web}
# Move originals
mv *.jpg originals/
# Create optimized copies
for img in originals/*.jpg; do
base=$(basename "$img")
magick "$img" -resize 2000x2000\> -quality 85 -strip "web/$base"
done
```