Almost user-friendly bulk image optimization in CLI

  •   4 minutes read
Let’s optimize the whole directories of images without losing visual quality. Simple reduce files sizes and convert animated GIFs to modern video formats. Why? Conversion animated GIFs into video rapidly saves space and network bandwidth and gives the user the capability to pause or slow down the animation.

Prerequisites

Don’t be afraid of the command line, have node.js installed.

Global imagemin installation

npm i -g imagemin

PNG optimization

Prerequisites: install imagemin and upng plugin globally.

npm i -g imagemin imagemin-upng

Optimize all files in the source directory and save them in the optimized directory.

imagemin -p=upng source/*.png -o=optimized

Input: 2446 files with file sizes between 177 KB to 2,3 MB.
Result: 109.5 MB → 43.7 MB ~ 60% saving.

PNG conversion to WEBP

⚠️ I don’t recommend it because it mainly produces bigger files than the upng method from the previous chapter. Savings are minimal—18% bigger than upng.

Prerequisites: install imagemin and webp plugin globally.

npm i -g imagemin imagemin-webp

Optimize all files in the source directory and save them in the optimized directory.

imagemin -p.webp.lossless=true source/*.png -o=optimized

Input: 2446 files with file sizes between 177 KB to 2,3 MB.
Result: 109.5 MB → 53.2 MB ~ 51% saving.

GIF optimization

Prerequisites: install imagemin and gifsicle plugin globally.

npm i -g imagemin imagemin-gifsicle

Optimize all files in the source directory and save them in the optimized directory.

imagemin -p.gifsicle.optimizationLevel=3 source/*.gif -o=optimized

Input: 1020 files with file sizes between 8.8 KB to 6.2 MB.
Result: 428 MB → 390.5 MB ~ 9% saving.

GIF conversion to WEBP

⚠️ I don’t recommend it because it mainly produces bigger files than the original files. Savings are minimal.

Prerequisites: install imagemin and webp plugin globally.

npm i -g imagemin imagemin-webp

Optimize all files in the source directory and save them in the optimized directory.

imagemin -p.webp.lossless=true source/*.gif -o=optimized

Input: 1020 files with file sizes between 8.8 KB to 6.2 MB.
Result: 428 MB → 360.2 MB ~ 16% saving.

GIF conversion to MP4

Highly recommended! Conversion animated GIFs into video rapidly saves space and network bandwidth and gives the user the capability to pause or slow down the animation.

Prerequestions: install ffmepg (on Windows)

  1. Download latest ffmpeg-git-full.7z
  2. Extract files to directory ffmpeg in the root if C: drive.
  3. Now, run cmd as an administrator and set the environment path variable for ffmpeg by running the following command: setx /m PATH "C:\ffmpeg\bin;%PATH%"
  4. Restart your cmd and verify the installation by running: ffmpeg -version

Code contains an ideal ffmepg preset for converting the GIFs into MP4s. The command goes through all GIF files in the current directory, converts them into MP4 files and saves them with the same filename.

for i in *.gif;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "${name}.mp4"
done

Input: 1020 files with file sizes between 8.8 KB to 6.2 MB.
Result: 428 MB → 197.2 MB ~ 54% saving.

SVG optimization

Optimize all files in the source directory and save them in the optimized directory.

npx svgo -f source -o optimized

JPEG optimization with mozjpeg

Prerequisites: install imagemin and mozjpeg plugin globally.

npm i -g imagemin imagemin-mozjpeg

Optimize all files in the source directory and save them in the optimized directory.

imagemin -p.mozjpeg.progressive=true.dcScanOpt=2.tune=ms-ssim source/*.* -o=optimized

JPEG optimization with guetzli

⚠️ Recommended only for really high-quality images. Consumes significant computational resources.

Prerequisites: install imagemin and guetzli plugin globally.

npm i -g imagemin imagemin-guetzli

Optimize all files in the source directory and save them in the optimized directory.

imagemin -p.guetzli source/*.jpg -o=optimized

Wrap up

Install imagemin with plugins globally. You only need to run it once on the computer.

npm i -g imagemin imagemin-upng imagemin-gifsicle imagemin-mozjpeg imagemin-svgo

Paste this bash function to enable process files in bundles of 100 files because many files in the buffer require significant computational resources. Not optimized files will be copied. Paste it only once after the bash window is opened.

set -euo pipefail
IFS=$'\n\t'

function optimizeImages()
{
    local DIRECTORY="$1"
    local GROUP_SIZE=100
    local FILES
    readarray -t FILES < <(find "${DIRECTORY}/" -maxdepth 1 -type f)

    local INDEX
    for (( INDEX=0; INDEX<${#FILES[@]}; INDEX+=GROUP_SIZE )); do
        local PART=("${FILES[@]:INDEX:GROUP_SIZE}")
        imagemin -p=upng -p.gifsicle.optimizationLevel=3 -p.mozjpeg.progressive=true.dcScanOpt=2.tune=ms-ssim -p=svgo ${part[*]} -o=optimized
    done
}

Execute optimization by writing function name and image source folder optimizeImages source and pressing the enter key.