Dua file bernama photo.jpg dan photo.png di direktori yang sama akan menghasilkan nama tujuan yang identik: photo.webp. Jika benturan baru diketahui saat konversi berlangsung, salah satu gambar bisa terlewat atau hasil sebelumnya tertimpa. Daftar input sebaiknya diperiksa sebelum encoding dimulai.
Script Bash berikut memakai cwebp dan menyimpan hasil dalam struktur direktori terpisah. Mode auto secara default memakai WebP lossy untuk JPEG dan WebP lossless untuk PNG. File sumber tetap utuh, sedangkan file tujuan yang sudah ada akan dilewati.
Petakan file sumber ke tujuan yang berbeda
Struktur subdirektori dipertahankan: images/products/front.jpg menjadi webp/products/front.webp. Script menolak direktori hasil di dalam direktori sumber agar hasil eksekusi sebelumnya tidak ikut diproses. Pasangan seperti front.jpg dan front.png juga diperiksa sebelum konversi; jika keduanya menuju nama yang sama, proses dihentikan tanpa memilih salah satunya secara diam-diam.
Daftar file menggunakan pemisah NUL. Kombinasi find -print0 dan read -d '' membuat spasi maupun baris baru dalam nama file tetap terbaca sebagai bagian dari satu path. Daftar tersebut disimpan dalam manifest agar kegagalan find menghentikan proses sebelum encoding, bukan tersembunyi dalam pipeline. Detailnya ada di dokumentasi GNU find tentang penanganan nama file.
Script Bash
Simpan sebagai batch-to-webp.sh. Script ini membutuhkan Bash 4 atau lebih baru, cwebp, serta utilitas GNU find, realpath, mktemp, dan ln.
#!/usr/bin/env bash
set -euo pipefail
if (( $# < 2 || $# > 4 )); then
printf 'Usage: %s SOURCE_DIR OUTPUT_DIR [QUALITY] [auto|lossy|lossless]\n' "$0" >&2
exit 2
fi
quality=${3:-80}
mode=${4:-auto}
if [[ ! -d $1 || ! $quality =~ ^(100|[1-9]?[0-9])$ ]]; then
printf 'Use an existing source directory and a quality from 0 to 100.\n' >&2
exit 2
fi
case "$mode" in
auto|lossy|lossless) ;;
*) printf 'Mode must be auto, lossy, or lossless.\n' >&2; exit 2 ;;
esac
for tool in cwebp find realpath mktemp ln; do
if ! command -v "$tool" >/dev/null 2>&1; then
printf 'Missing command: %s\n' "$tool" >&2
exit 1
fi
done
source=$(realpath -e -- "$1")
output=$(realpath -m -- "$2")
if [[ $output == "$source" || $output == "$source/"* ]]; then
printf 'Place the output directory outside the source tree.\n' >&2
exit 2
fi
mkdir -p -- "$output"
output=$(realpath -e -- "$output")
manifest=$(mktemp -- "$output/.webp-inputs.XXXXXXXX")
tmp=''
cleanup() {
if [[ -n $tmp ]]; then rm -f -- "$tmp"; fi
rm -f -- "$manifest"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
find "$source" -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) -print0 > "$manifest"
declare -A claimed=()
while IFS= read -r -d '' input; do
relative=${input#"$source"/}
target="$output/${relative%.*}.webp"
if [[ -n ${claimed[$target]+present} ]]; then
printf 'Conflicting names: %q and %q both map to %q\n' \
"${claimed[$target]}" "$relative" "$target" >&2
exit 1
fi
claimed["$target"]=$relative
done < "$manifest"
converted=0
skipped=0
failed=0
while IFS= read -r -d '' input; do
relative=${input#"$source"/}
target="$output/${relative%.*}.webp"
if [[ -e $target || -L $target ]]; then
((skipped += 1))
continue
fi
mkdir -p -- "${target%/*}"
tmp=$(mktemp -- "${target%/*}/.webp.XXXXXXXX")
options=(-q "$quality")
if [[ $mode == lossless || ( $mode == auto && ${input,,} == *.png ) ]]; then
options=(-lossless -q "$quality")
fi
if cwebp -quiet "${options[@]}" "$input" -o "$tmp" && ln -- "$tmp" "$target"; then
((converted += 1))
elif [[ -e $target || -L $target ]]; then
((skipped += 1))
else
((failed += 1))
printf 'Failed: %q\n' "$relative" >&2
fi
rm -f -- "$tmp"
tmp=''
done < "$manifest"
printf 'Converted: %d | skipped: %d | failed: %d\n' \
"$converted" "$skipped" "$failed"
(( failed == 0 ))Pada Debian atau Ubuntu, instal paket webp lalu jalankan script dengan direktori sumber, direktori tujuan yang terpisah, serta argumen kualitas dan mode jika diperlukan:
sudo apt install webp
chmod +x batch-to-webp.sh
./batch-to-webp.sh ./images ./webp 80 auto
./batch-to-webp.sh ./images ./webp-lossy 75 lossyKualitas default adalah 80 dengan mode auto. Mode lossy mengubah seluruh input menjadi WebP lossy, sedangkan lossless menggunakan WebP lossless untuk semua input. Gunakan direktori tujuan lain saat membandingkan pengaturan, karena hasil yang sudah ada memang tidak dibuat ulang.
Pilihan encoding berbeda dari pilihan metadata
Pada encoding lossy, cwebp -q 80 mengorbankan sebagian detail gambar untuk mengurangi ukuran. Arti -q berubah saat -lossless digunakan: nilai lebih tinggi memberi encoder lebih banyak upaya kompresi dan dapat menghasilkan file lebih kecil, tanpa sengaja membuang detail piksel hasil decode. Mengubah JPEG ke WebP lossless tidak mengembalikan informasi yang sudah hilang ketika JPEG tersebut dibuat.
Konversi PNG secara lossless mempertahankan detail piksel yang terlihat dan transparansi. Namun, cwebp tidak mempertahankan nilai RGB pada piksel yang sepenuhnya transparan kecuali opsi -exact digunakan. Perbedaannya terasa jika proses pengolahan berikutnya membutuhkan informasi warna tersembunyi tersebut. Ukuran hasil lossless juga tidak selalu lebih kecil daripada PNG asal.
Secara default, cwebp tidak menyalin metadata EXIF, ICC, maupun XMP. Ini dapat menghilangkan data lokasi yang tidak perlu pada aset web, tetapi juga dapat membuang profil warna atau tag orientasi EXIF yang dibutuhkan foto agar tampil sesuai harapan. Jika diperlukan, normalkan orientasi sebelum konversi atau gunakan -metadata exif,icc setelah memeriksa metadata sumber. Referensi cwebp menjelaskan opsi tersebut beserta batasan tiap format.
Simpan hasil tanpa menimpa file lain
Setiap gambar diencode ke file sementara di direktori tujuan. Setelah cwebp berhasil, ln membuat nama file akhir hanya jika nama tersebut belum ada. Nama sementara kemudian dihapus, sementara file WebP yang selesai tetap tersimpan. Dengan cara ini, file tujuan tidak akan terlihat saat isinya baru terisi sebagian, dan proses lain tidak bisa membuat script menimpa hasil yang muncul setelah pemeriksaan awal.
Gambar rusak atau berformat tidak sesuai ekstensi dihitung sebagai kegagalan, tetapi input berikutnya tetap diproses. Status akhir bernilai bukan nol jika ada konversi yang gagal. Saat dijalankan ulang, hasil yang sudah ada dilewati; mekanisme ini membantu setelah proses terputus, tetapi tidak mendeteksi perubahan pada gambar sumber. Gunakan direktori tujuan baru setelah mengganti gambar, kualitas, atau mode encoding.
Script memproses file satu per satu sehingga tidak menjalankan banyak decoder sekaligus. Meski begitu, satu gambar beresolusi sangat tinggi tetap dapat memakai memori besar. Jika profil warna, orientasi foto, atau ukuran hasil penting, periksa beberapa gambar hasil terlebih dahulu sebelum mengganti referensi ke file asli.