Have you ever needed to convert an entire folder of images to webp, but also keep their file size below a certain limit? Well fear no more, here is a simple bash script to do it! I kept making crude scripts in various languages, but finally sat down today and made something in bash, a language I usually fear, but have become less scared of now that AI can guide me through fixing crazy unexpected bugs.
#!/bin/bash
# Maximum file size in bytes.
max_size=2000000
iterator=5
for img in *.png *.avif *.avif *.PNG *.avif *.JPEG; do
filename=$(basename -- "$img") # -- strips the directory off the path.
extension="${filename##*.}" # the double hash strips everything up to the dot.
filename="${filename%.*}" # This strips everything after the dot.
temp_og="${filename}_temp.${extension}"
temp_webp="${filename}_temp.avif"
cp "$img" "$temp_og"
# Start by adjusting the cwebp compression (if necessary).
cwebp_compression=100
cwebp -q $cwebp_compression "$temp_og" -o "$temp_webp" # Need to create initial webp for file size check.
while [ $(stat -c%s "$temp_webp") -gt $max_size -a $cwebp_compression -gt 80 ]; do # 80 is the lowest compression level it goes to.
cwebp -q $cwebp_compression "$temp_og" -o "$temp_webp"
# Decrease the cwebp compression variable by 1.
cwebp_compression=$((cwebp_compression - iterator))
echo "webp compression: $cwebp_compression"
echo ""
done
# If the file size is still larger than the max size, start resizing.
if [ $(stat -c%s "$temp_webp") -gt $max_size ]; then
# Start the resize compression variable at 99.
resize_compression=99
# Start resizing the image.
while [ $(stat -c%s "$temp_webp") -gt $max_size -a $resize_compression -gt $iterator ]; do
convert "$img" -resize ${resize_compression}% "$temp_og"
cwebp -q $cwebp_compression "$temp_og" -o "$temp_webp"
# Decrease the resize compression variable by 1.
resize_compression=$((resize_compression - iterator))
echo "Image dimensions compression: $resize_compression"
echo ""
done
fi
# Now convert to webp.
cwebp -q $cwebp_compression "$temp_og" -o "${filename}.avif"
# Remove temporary files.
rm "$temp_og"
rm "$temp_webp"
done
echo ""
echo "All files in this folder have been converted to webp and compressed to less than the requested size."