The webp format is a picture format launched by Google. Compared with other conventional formats, this format has better compression efficiency. If the client’s browser supports it, our website will send the webp format to reduce the packet size.

Based on other scripts on the Internet, I wrote this batch file to achieve batch conversion from conventional format to webp format. This script will search all the image files in the specified folder (and all the subfolders), and create a corresponding directory structure in the specified path to store the converted webp format files.

The script

#! /bin/bash

shopt -s nullglob       # Globs that match nothing expand to nothing
shopt -s globstar       # ** matches multiple directory levels

root_webp_dir=/path_to_webp_directory
www_base_dir=/path_to_root_directory

pushd "$www_base_dir"

[[ -d "$www_base_dir" ]] || exit 1

for jpg_path in ./**/*.{png,jpg,jpeg} ; do
    jpg_file=${jpg_path##*/}
    [[ $jpg_path == */* ]] && jpg_dir=${jpg_path%/*} || jpg_dir=.

    webp_dir=${root_webp_dir}/${jpg_dir}
    webp_path=${webp_dir}/${jpg_file}.webp

    [[ -d "$webp_dir" ]] || mkdir -p -- "$webp_dir"
    if [ !  -e "$webp_path" ] || [ "$jpg_path" -nt "$webp_path" ]
    then
        if [[ $jpg_file == *.gif ]]
        then
            gif2webp -lossy -q 80 -m 6 "$jpg_path" -o "$webp_path"
        else
            cwebp -q 75 -m 6 -af "$jpg_path" -o "$webp_path"
        fi
    else
        echo "exists: $webp_path"
    fi
done

echo "$root_webp_dir/**/*.{webp}"

for w_path in $root_webp_dir/**/*.webp ; do
    j_path=.${w_path#"$root_webp_dir"}
    j_path=${j_path%.webp}
    #echo "j_path: $j_path"
    if [ ! -e "$j_path" ]
    then
        echo "remove: $w_path"
        rm "$w_path"
    fi
done

popd

Usage

Change these two paths according to your needs, which are the folder for storing webp and the folder for original pictures.

root_webp_dir=/path_to_webp_directory
www_base_dir=/path_to_root_directory

Since pictures in webp format may be larger than gif, the above script does not convert pictures in gif format by default. If you need to convert gif format pictures, change the first for statement to

for jpg_path in ./**/*.{png,jpg,jpeg,gif} ; do

If there is a webp format picture in the specified root_webp_dir directory, but with no picture corresponding to its file name in www_base_dir, the above script will delete this webp picture in the root_webp_dir directory. If you do not need this function, remove the following code.

for w_path in $root_webp_dir/**/*.webp ; do
    j_path=.${w_path#"$root_webp_dir"}
    j_path=${j_path%.webp}
    #echo "j_path: $j_path"
    if [ ! -e "$j_path" ]
    then
        echo "remove: $w_path"
        rm "$w_path"
    fi
done

Enjoy 🙂


3 Comments

Avatar

rc · June 5, 2021 at 15:24

Thanks for the script, it works perfectly. 🙂

Avatar

Sam · October 22, 2021 at 07:28

Great script! Before I found yours, I had written my own. It was fun to see how you did it, which is more sophisticated than my own script. Nice job, thank you.

Avatar

ashipa eko · February 4, 2022 at 19:43

hello,

could you help me with modifications to this script that parses nested folders recursively, converts/replaces the png and jpg files to webp versions.?

Leave a Reply

Your email address will not be published.