πŸ’Š Quick Pill: Batch Image Optimization

πŸš€ Quick Setup

Install Required Tools

# Ubuntu/Debian
sudo apt install jpegoptim optipng

# Fedora/RHEL
sudo dnf install jpegoptim optipng

# macOS (with Homebrew)
brew install jpegoptim optipng

πŸ“Έ Basic Image Optimization

Optimize All JPEGs in Folder

Save as optimize_images.sh:

#!/bin/bash

# Go to your images folder
cd imgfolder

# Find and optimize all JPEGs
find . -type f -name "*.jpg" -exec jpegoptim -P --max=35 --strip-all {} \;

What it does:

  • find . -type f -name "*.jpg": Finds all .jpg files recursively
  • -exec jpegoptim: Runs jpegoptim on each file
  • -P: Preserve file modification time
  • --max=35: Set quality to 35% (aggressive compression)
  • --strip-all: Remove all metadata (EXIF, GPS, etc.)

Run the Script

chmod +x optimize_images.sh
./optimize_images.sh

🎨 Quality Levels Guide

JPEG Quality Settings

QualityUse CaseFile SizeVisual Quality
--max=35Thumbnails, aggressive compressionVery smallAcceptable
--max=50Web images, blog postsSmallGood
--max=70Standard web useMediumVery good
--max=85High quality webLargerExcellent
--max=95Print, professionalLargeNear original

Choose Your Quality

# Thumbnails - maximum compression
find . -name "*.jpg" -exec jpegoptim --max=35 --strip-all {} \;

# Web images - balanced
find . -name "*.jpg" -exec jpegoptim --max=70 --strip-all {} \;

# High quality - minimal loss
find . -name "*.jpg" -exec jpegoptim --max=85 --strip-all {} \;

πŸ’‘ Pro Tips

Optimize specific folder recursively
#!/bin/bash

# Set your folder path
IMAGE_FOLDER="/path/to/images"
QUALITY=70

echo "Optimizing images in: $IMAGE_FOLDER"
echo "Quality setting: $QUALITY"

# Count images first
TOTAL=$(find "$IMAGE_FOLDER" -type f \( -name "*.jpg" -o -name "*.jpeg" \) | wc -l)
echo "Found $TOTAL images to optimize"

# Optimize
find "$IMAGE_FOLDER" -type f \( -name "*.jpg" -o -name "*.jpeg" \) \
    -exec jpegoptim -P --max=$QUALITY --strip-all {} \;

echo "βœ… Optimization complete!"
Optimize both .jpg and .jpeg extensions
# Handle both extensions
find . -type f \( -name "*.jpg" -o -name "*.jpeg" \) \
    -exec jpegoptim -P --max=70 --strip-all {} \;
Keep EXIF data (camera info, date, etc.)
# Preserve EXIF but remove other metadata
find . -name "*.jpg" -exec jpegoptim -P --max=70 --all-progressive {} \;

# Or keep all metadata
find . -name "*.jpg" -exec jpegoptim -P --max=70 {} \;
Optimize PNG images too
#!/bin/bash

echo "Optimizing JPEGs..."
find . -name "*.jpg" -exec jpegoptim -P --max=70 --strip-all {} \;

echo "Optimizing PNGs..."
find . -name "*.png" -exec optipng -o2 {} \;

echo "βœ… All images optimized!"

PNG optimization levels:

  • -o2: Fast, good compression
  • -o5: Balanced (default)
  • -o7: Best compression, slower
Create backup before optimizing
#!/bin/bash

FOLDER="imgfolder"
BACKUP="${FOLDER}_backup_$(date +%Y%m%d_%H%M%S)"

echo "Creating backup: $BACKUP"
cp -r "$FOLDER" "$BACKUP"

echo "Optimizing images in $FOLDER..."
cd "$FOLDER"
find . -name "*.jpg" -exec jpegoptim -P --max=70 --strip-all {} \;

echo "βœ… Done! Backup saved in: $BACKUP"
Show size savings statistics
#!/bin/bash

FOLDER="imgfolder"

# Calculate size before
BEFORE=$(du -sh "$FOLDER" | cut -f1)
echo "Size before: $BEFORE"

# Optimize
cd "$FOLDER"
find . -name "*.jpg" -exec jpegoptim -P --max=70 --strip-all {} \; | tee /tmp/optim.log

# Calculate size after
AFTER=$(du -sh "$FOLDER" | cut -f1)
echo "Size after: $AFTER"

# Show summary
echo ""
echo "=== Optimization Summary ==="
grep -E "optimized|skipped" /tmp/optim.log | tail -5
Optimize only images larger than X KB
# Only optimize images larger than 500KB
find . -name "*.jpg" -size +500k \
    -exec jpegoptim -P --max=70 --strip-all {} \;

# Only optimize images larger than 1MB
find . -name "*.jpg" -size +1M \
    -exec jpegoptim -P --max=70 --strip-all {} \;
Resize AND optimize (for web)

Install ImageMagick first: sudo apt install imagemagick

#!/bin/bash

# Resize to max width 1920px AND optimize
find . -name "*.jpg" -exec sh -c '
    convert "$1" -resize "1920x1920>" -quality 70 "$1"
    jpegoptim -P --strip-all "$1"
' _ {} \;

echo "βœ… Resized and optimized!"
Create web-optimized copies (keep originals)
#!/bin/bash

SOURCE="originals"
OUTPUT="web_optimized"

# Create output folder
mkdir -p "$OUTPUT"

# Copy and optimize
find "$SOURCE" -name "*.jpg" -type f | while read file; do
    # Get relative path
    rel_path="${file#$SOURCE/}"
    out_file="$OUTPUT/$rel_path"
    
    # Create directory structure
    mkdir -p "$(dirname "$out_file")"
    
    # Copy and optimize
    cp "$file" "$out_file"
    jpegoptim -P --max=70 --strip-all "$out_file"
done

echo "βœ… Web-optimized copies created in: $OUTPUT"

πŸ” Understanding jpegoptim Options

Common Options

OptionDescriptionWhen to Use
--max=NSet maximum quality (0-100)Always - controls compression
--strip-allRemove all metadataWeb use, privacy
--strip-exifRemove only EXIF dataRemove GPS/camera info
--strip-comRemove commentsClean up files
-PPreserve file timestampsKeep original dates
--all-progressiveProgressive JPEGsBetter web loading
--all-normalBaseline JPEGsMaximum compatibility
--size=NTarget file size in KBStrict size limits

Example Combinations

# Web thumbnails - aggressive
jpegoptim --max=40 --strip-all --all-progressive image.jpg

# Blog post images - balanced
jpegoptim --max=70 --strip-all -P image.jpg

# Photography website - high quality
jpegoptim --max=90 --strip-com -P image.jpg

# Target specific file size
jpegoptim --size=100k image.jpg  # Max 100KB

πŸ“Š Common Use Cases

Website Optimization

#!/bin/bash
# Optimize all images for website deployment

echo "🌐 Optimizing for web..."

# Hero images - high quality
find ./images/hero -name "*.jpg" -exec jpegoptim -P --max=85 --strip-all {} \;

# Blog images - medium quality
find ./images/blog -name "*.jpg" -exec jpegoptim -P --max=70 --strip-all {} \;

# Thumbnails - low quality
find ./images/thumbs -name "*.jpg" -exec jpegoptim -P --max=40 --strip-all {} \;

echo "βœ… Website images optimized!"

Social Media Preparation

# Instagram/Facebook ready
find . -name "*.jpg" -exec jpegoptim --max=80 --strip-all {} \;

# Twitter (smaller files)
find . -name "*.jpg" -exec jpegoptim --max=70 --strip-all {} \;

Email Attachments

# Reduce for email (target ~500KB per image)
find . -name "*.jpg" -exec jpegoptim --size=500k --strip-all {} \;

Photo Archive Compression

# Compress old photos (keep EXIF for dates)
find ./archive -name "*.jpg" -exec jpegoptim --max=75 -P {} \;

⚠️ Important Warnings

Safe Testing Workflow

# 1. Create test folder with copies
mkdir test_optimization
cp imgfolder/*.jpg test_optimization/

# 2. Test optimization
cd test_optimization
jpegoptim --max=70 --strip-all *.jpg

# 3. Review results
ls -lh  # Check file sizes
# Open images and check quality

# 4. If satisfied, optimize originals
cd ../imgfolder
jpegoptim --max=70 --strip-all *.jpg
# Thumbnails (100-200px)
--max=35

# Social media posts
--max=70

# Blog/website images
--max=75

# Portfolio/photography site
--max=85

# Print preparation
--max=95

# Icons/logos (use PNG instead!)
# jpegoptim not recommended

πŸ”§ Troubleshooting

jpegoptim: command not found

Problem: Tool not installed

Solution:

# Ubuntu/Debian
sudo apt update && sudo apt install jpegoptim

# Check installation
jpegoptim --version
Images look terrible after optimization

Problem: Quality setting too aggressive

Solution:

# Restore from backup
cp -r imgfolder_backup/* imgfolder/

# Use higher quality
find imgfolder -name "*.jpg" -exec jpegoptim --max=80 --strip-all {} \;
Permission denied errors

Problem: No write access to files

Solution:

# Change ownership if needed
sudo chown -R $USER:$USER imgfolder/

# Or run with sudo (not recommended)
sudo find . -name "*.jpg" -exec jpegoptim --max=70 --strip-all {} \;
Script optimization is too slow

Problem: Processing thousands of images

Solution:

# Use parallel processing (install GNU parallel first)
sudo apt install parallel

# Optimize in parallel (4 jobs at once)
find . -name "*.jpg" | parallel -j4 jpegoptim -P --max=70 --strip-all {}

# Much faster on multi-core systems!

πŸ“ˆ Expected Size Reductions

Original Qualitymax=35max=50max=70max=85
High-res photo~90%~75%~50%~30%
Already compressed~30%~20%~10%~5%
Screenshots~80%~65%~40%~20%

πŸš€ Advanced One-Liners

# Optimize, show progress, count files
find . -name "*.jpg" | tee >(wc -l) | xargs -I {} jpegoptim --max=70 {}

# Optimize only recent files (last 7 days)
find . -name "*.jpg" -mtime -7 -exec jpegoptim --max=70 --strip-all {} \;

# Optimize by file size (>500KB only)
find . -name "*.jpg" -size +500k -exec jpegoptim --max=70 --strip-all {} \;

# Optimize and log results
find . -name "*.jpg" -exec jpegoptim --max=70 --strip-all {} \; > optimization.log

# Remove GPS data only (keep other EXIF)
find . -name "*.jpg" -exec exiftool -gps:all= {} \;

πŸ“‹ Complete Optimization Script

Save as optimize_all.sh:

#!/bin/bash

# Configuration
SOURCE_FOLDER="${1:-.}"  # Default to current folder
QUALITY="${2:-70}"       # Default quality 70
BACKUP=true              # Set to false to skip backup

echo "================================================"
echo "  Image Optimization Script"
echo "================================================"
echo "Folder: $SOURCE_FOLDER"
echo "Quality: $QUALITY"
echo ""

# Create backup if enabled
if [ "$BACKUP" = true ]; then
    BACKUP_FOLDER="${SOURCE_FOLDER}_backup_$(date +%Y%m%d_%H%M%S)"
    echo "Creating backup: $BACKUP_FOLDER"
    cp -r "$SOURCE_FOLDER" "$BACKUP_FOLDER"
fi

# Count files
TOTAL_JPG=$(find "$SOURCE_FOLDER" -type f \( -name "*.jpg" -o -name "*.jpeg" \) | wc -l)
TOTAL_PNG=$(find "$SOURCE_FOLDER" -type f -name "*.png" | wc -l)

echo "Found $TOTAL_JPG JPEG files"
echo "Found $TOTAL_PNG PNG files"
echo ""

# Size before
SIZE_BEFORE=$(du -sh "$SOURCE_FOLDER" | cut -f1)
echo "Size before: $SIZE_BEFORE"
echo ""

# Optimize JPEGs
if [ $TOTAL_JPG -gt 0 ]; then
    echo "Optimizing JPEGs..."
    find "$SOURCE_FOLDER" -type f \( -name "*.jpg" -o -name "*.jpeg" \) \
        -exec jpegoptim -P --max=$QUALITY --strip-all {} \;
fi

# Optimize PNGs
if [ $TOTAL_PNG -gt 0 ]; then
    echo ""
    echo "Optimizing PNGs..."
    find "$SOURCE_FOLDER" -type f -name "*.png" -exec optipng -o2 -quiet {} \;
fi

# Size after
SIZE_AFTER=$(du -sh "$SOURCE_FOLDER" | cut -f1)

echo ""
echo "================================================"
echo "  Optimization Complete!"
echo "================================================"
echo "Size before: $SIZE_BEFORE"
echo "Size after:  $SIZE_AFTER"
if [ "$BACKUP" = true ]; then
    echo "Backup: $BACKUP_FOLDER"
fi
echo ""

Usage:

chmod +x optimize_all.sh

# Optimize current folder, quality 70
./optimize_all.sh

# Optimize specific folder, quality 80
./optimize_all.sh /path/to/images 80

Optimize your images for faster websites and smaller storage!