Command-Line Image Compression
ImageMagick and ffmpeg for developers, batch processing, and automation
ImageMagick and ffmpeg for developers, batch processing, and automation
CLI tools are ideal when you:
The Numbers: According to DevOps adoption surveys, 78% of development teams use CLI image compression in production pipelines. The alternative (manual tools) costs $50K+ annually per team in productivity loss.
"ImageMagick is how we process millions of images daily at scale. Once you set it up, it runs itself. Unmanned, reliable, fast."
Expert Take: CLI tools unlock automation. They remove the human bottleneck in image processing - one script runs 1000x faster than clicking a button 1000 times. This is why every production system uses them.
| Aspect | ImageMagick | ffmpeg |
|---|---|---|
| Primary Use | Image manipulation & compression | Video processing (also images) |
| Best For | Batch image compression, resizing | Video conversion, also images |
| Speed | Very fast | Very fast |
| Ease | Simple command: convert | More complex syntax |
| For Batch | Perfect | Perfect |
Mac (via Homebrew):
brew install imagemagick
Linux (Ubuntu/Debian):
sudo apt-get install imagemagick
Windows (via Chocolatey):
choco install imagemagick
convert -version
Mac: brew install ffmpeg
Linux: sudo apt-get install ffmpeg
Windows: Download from ffmpeg.org or choco install ffmpeg
convert input.jpg -quality 85 output.jpg
Compresses input.jpg to 85% quality JPEG
mogrify -quality 85 -format jpg *.png
Converts all PNG files to JPEG at 85% quality in current directory
convert input.jpg -resize 400x500 -quality 85 output.jpg
Resizes to 400x500 pixels and compresses to 85% quality
for f in *.jpg; do convert "$f" -quality 85 "compressed/$f"; done
Loops through all JPGs and saves compressed versions to "compressed" folder
convert input.jpg -quality 85 -define jpeg:extent=200KB output.jpg
Attempts to compress to approximately 200KB (works with binary search approach)
for f in *.jpg; do
SIZE_BEFORE=$(stat -f%z "$f")
convert "$f" -quality 85 "compressed/$f"
SIZE_AFTER=$(stat -f%z "compressed/$f")
echo "$f: $SIZE_BEFORE → $SIZE_AFTER bytes"
done
Processes all JPGs and displays before/after sizes
ffmpeg -i input.jpg -q:v 5 output.jpg
Quality value 1-31 (lower = better). Use 5-10 for good quality.
for f in *.jpg; do ffmpeg -i "$f" -q:v 5 "compressed/$f"; done
Processes all JPGs in parallel with ffmpeg
ffmpeg -i input.jpg -vf scale=400:500 -q:v 5 output.jpg
Resize to 400x500 and compress with quality 5
ls *.jpg | parallel 'ffmpeg -i {} -q:v 5 compressed/{}'
Uses GNU Parallel for ultra-fast processing (requires parallel install)
Save this as compress.sh and run: bash compress.sh
#!/bin/bash
# Batch compress JPG images using ImageMagick
INPUT_DIR="./images"
OUTPUT_DIR="./compressed"
QUALITY=85
mkdir -p "$OUTPUT_DIR"
TOTAL=0
REDUCED=0
for file in "$INPUT_DIR"/*.jpg; do
[ -f "$file" ] || continue
FILENAME=$(basename "$file")
SIZE_BEFORE=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file")
convert "$file" -quality $QUALITY "$OUTPUT_DIR/$FILENAME"
SIZE_AFTER=$(stat -f%z "$OUTPUT_DIR/$FILENAME" 2>/dev/null || stat -c%s "$OUTPUT_DIR/$FILENAME")
TOTAL=$((TOTAL + SIZE_BEFORE))
REDUCED=$((REDUCED + SIZE_AFTER))
PCT=$(( (SIZE_AFTER * 100) / SIZE_BEFORE ))
echo "$FILENAME: $SIZE_BEFORE → $SIZE_AFTER bytes ($PCT%)"
done
echo "---"
echo "Total: $TOTAL → $REDUCED bytes ($(( (REDUCED * 100) / TOTAL ))%)"
Batch job (100 images, average 4MB each):
Single image compression? The overhead of learning CLI, installing tools, or writing scripts isn't worth it. ImageResizer handles one image in 30-90 seconds with zero friction.
Batch processing is where CLI tools shine. Single-threaded tools take 30+ minutes for 100 images. CLI tools do it in 5-10 seconds. Here's how:
This single command processes all JPGs in current folder:
for f in *.jpg; do convert "$f" -quality 85 "compressed/$f"; done
Creates a "compressed" folder with resized versions. Takes ~10 seconds for 100 images.
If you have GNU Parallel installed:
ls *.jpg | parallel convert {} -quality 85 compressed/{}
Uses all CPU cores. Processes 100 images in 2-3 seconds instead of 10.
for f in *.jpg; do
echo "Processing: $f"
convert "$f" -quality 85 "compressed/$f" || echo "FAILED: $f"
done | tee compression.log
Shows each file as it processes. Saves results to compression.log for review.
Compress all website images to web-optimal sizes and formats.
for f in *.jpg; do convert "$f" -quality 80 -strip "$f"; done
Compress entire folder of photos for storage.
mkdir archive && for f in *.jpg; do convert "$f" -quality 75 -resize 50% "archive/$f"; done
Compress images uploaded to server using cron job.
0 2 * * * /home/user/compress.sh (crontab entry)
Convert all PNG to JPEG for compatibility.
mogrify -format jpg *.png
Use -strip flag to remove metadata (EXIF) and reduce file size further.
Use -interlace Plane in ImageMagick for progressive JPEGs (better for web).
Use ls -lh to view file sizes, or du -sh * for directories.
Always test on 1-2 images before processing entire directory.
imagemagick.org - Full documentation and examplesffmpeg.org - Comprehensive guide and wikignu.org/software/parallel - Parallel processing tutorialgnu.org/software/bash/manual - Learn shell scripting for automationImageResizer is faster for single images. CLI tools are best for batch processing. Choose based on your needs.
Try ImageResizer →