Batch Convert Images to WebP: Scripts and Automation

Batch convert entire folders of JPEG and PNG images to WebP using shell scripts, find commands, and parallel processing for fast, automated workflows.

Converting an entire library of images to WebP is straightforward with shell scripts and the cwebp CLI. This guide shows you how to process folders of images efficiently, preserve directory structure in your output, and run conversions in parallel to take full advantage of multi-core hardware.

Always keep your original image files. Lossy WebP compression is irreversible — once you discard the source JPEG or PNG, you cannot recover the original pixel data from the WebP output. Run all scripts against a copy of your image library, or write output to a separate directory.

Convert a Single Directory #

The quickest way to convert all images in the current working directory is a for loop. Use separate loops for JPEGs and PNGs to apply the appropriate quality setting to each format.

# Convert all JPEGs in current directory
for f in *.jpg; do
  cwebp -q 80 "$f" -o "${f%.jpg}.webp"
done

# Convert all PNGs to lossless WebP
for f in *.png; do
  cwebp -lossless "$f" -o "${f%.png}.webp"
done

Recursive Conversion Preserving Structure #

Use find to walk a directory tree and convert every matching file in place. The -exec flag runs cwebp once per file found.

# Find and convert all JPEGs recursively
find ./images -name '*.jpg' -type f -exec sh -c '
  out="${1%.jpg}.webp"
  cwebp -q 80 "$1" -o "$out"
' _ {} \;

The _ {} syntax passes the matched filename as $1 inside the inline shell script. The leading _ is a placeholder for $0 (the script name) and is required by POSIX sh -c.

Output to a Separate Directory #

Write all converted files into a dedicated output directory while preserving the relative subdirectory structure of the source tree. Save the following script as convert-to-webp.sh and make it executable with chmod +x convert-to-webp.sh.

#!/usr/bin/env bash
# convert-to-webp.sh — convert all JPEG/PNG to WebP in ./output/

INPUT_DIR="./images"
OUTPUT_DIR="./output"

mkdir -p "$OUTPUT_DIR"

find "$INPUT_DIR" -type f \( -name '*.jpg' -o -name '*.png' \) | while read -r file; do
  # Preserve relative path
  rel="${file#$INPUT_DIR/}"
  out="$OUTPUT_DIR/${rel%.*}.webp"
  mkdir -p "$(dirname "$out")"
  cwebp -q 80 "$file" -o "$out"
done

echo "Conversion complete."
  1. Set INPUT_DIR and OUTPUT_DIR — Edit the two variables at the top of the script to point to your source image folder and your desired output location.
  2. Run the script — Execute ./convert-to-webp.sh from the directory that contains both folders. The script creates OUTPUT_DIR automatically if it does not exist.
  3. Verify the output — Check that the subdirectory structure inside OUTPUT_DIR mirrors the source tree, and spot-check a few converted files for visual quality.

Parallel Conversion for Speed #

Processing images one at a time is slow on modern hardware. Use background jobs to run multiple cwebp processes concurrently and saturate all available CPU cores.

Background Jobs (bash) #

This approach uses bash’s built-in job control to limit concurrency to a fixed number of simultaneous processes — no additional tools required.

wait -n requires bash ≥ 4.3. macOS ships bash 3.2 by default; install a newer version with brew install bash or use GNU Parallel instead.

# Using background jobs (N at a time)
convert_file() {
  cwebp -q 80 "$1" -o "${1%.*}.webp"
}

for f in images/*.jpg; do
  convert_file "$f" &
  # Limit concurrency to 4 (requires bash >= 4.3)
  [ $(jobs -r | wc -l) -ge 4 ] && wait -n
done
wait

GNU Parallel #

GNU parallel provides more robust job control, progress reporting, and automatic CPU detection. Install it with brew install parallel or sudo apt install parallel.

# Convert all JPEGs using all available CPU cores
find ./images -name '*.jpg' | parallel 'cwebp -q 80 {} -o {.}.webp'

# Explicitly set the number of parallel jobs
find ./images -name '*.jpg' | parallel -j 8 'cwebp -q 80 {} -o {.}.webp'

For single-file encoding of large images, add the -mt flag to cwebp to enable multi-threaded encoding within that one process. For multi-file batches, parallel jobs give you a much larger throughput gain than -mt alone — combine both techniques for maximum speed.

Using ImageMagick mogrify for Batch Operations #

magick mogrify (ImageMagick 7) can batch-convert an entire directory in a single command. Use -path to redirect output to a new directory so the originals are never overwritten.

# Convert all JPEGs in a directory
# Output goes to ./webp_output/ to avoid overwriting originals
mkdir webp_output
magick mogrify -format webp -quality 80 -path ./webp_output *.jpg

Verifying Output #

After a batch run, compare total disk usage between the source and output directories to confirm the expected file-size reduction.

# Compare total size before and after
echo "Original:"
du -sh images/
echo "WebP output:"
du -sh output/

For a more detailed breakdown, generate a per-file size comparison report:

# List each WebP file alongside its size
find ./output -name '*.webp' -type f | while read -r f; do
  echo "$(du -sh "$f" | cut -f1) $f"
done

Don’t want to write scripts at all? Our free no-install batch WebP converter converts multiple images at once directly in your browser — no installation, no uploads, and no file-size limits.

Was this page helpful?