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.

Download the script

#!/bin/bash

# Maximum file size in bytes.
max_size=2000000
iterator=5

for img in *.png *.jpg *.jpeg *.PNG *.JPG *.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.webp"

	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}.webp"

	# 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."