grants.technology

Optimising Images for Display on Web

What is Image Optimisation and why should I care?

The most commonly supported images used on the web are JPEG (lossy), PNG (lossless, compressed) and GIF (limited colour palette). Often images contain ‘metadata’ that don’t add anything to the visual quality of the image - eg, type of camera and settings, GPS co-ordinates, time, date and so on.

On a typical blog, business page or eCommerce website, images are added over time using the Administrative back end features of CMSs such as WordPress, Drupal, Joomla!, Magento etc.

Many different roles within the organisation may be given access to upload images, and often these files and processes haven’t been optimised for web - increasing the file size by 30-80% with no corresponding increase in quality.

So image enter image optimisation. This is a collection of tools and techniques we can apply to reduce the size of the file dramatically, whilst decreasing the quality of the image as little as possible (if, at all), and improving the download time and responsiveness of the site.

As always, please test thoroughly and ensure you have a backup before using any of these tools or techniques in a Production environment.

Online Solutions for a small amount of images

There are a variety of well known and regarded online solutions that allow us to do this for individual images, and even batch several at a time, such as Kraken!, TinyPNG and Compressor.io. Although each of these services can offer a comparable benefit, what about if we have a large amount of images (hundreds, thousands or more) that might all require optimising?

Command Line Options for Large Amounts of images

CLI Tools

Presuming you’re using a modern version of Linux and can install the relevant tools using your distribution’s package manager, eg. homebrew (Mac OS X), apt (Debian/Ubuntu) or yum (RedHat, CentOS) the tools you’ll need to ensure you have installed include -

Installation

Debian / Ubuntu

apt-get update
apt-get install -y jpegoptim optipng gifsicle guetzli imagemagick

Mac OS X

Open Terminal: Spotlight Search, type ‘term’, open “terminal.app”

brew update
brew install jpegoptim optipng gifsicle guetzli imagemagick

Optimising a single image (JPEG)

Original Image: swiss-alps-orig.jpg 1.1MB Original Image: swiss-alps-orig.jpg 1.1MB

JPEG Optim Image: swiss-alps-jpegoptim.jpg 818KB JPEG Optim Image: swiss-alps-jpegoptim.jpg 818KB

Mac OS X Command: jpegoptim -m85 -o -p --strip-all swiss-alps-jpegoptim.jpg

Linux Command: jpegoptim --strip-all -P swiss-alps-jpegoptim.jpg

Example Output: swiss-alps-jpegoptim.jpg 3000x1716 24bit N Exif XMP IPTC JFIF  [OK] 1114034 --> 837295 bytes (24.84%), optimized.

Execution Time: <1s

Guetzli Optimised Image: swiss-alps-guetzli.jpg 526K swiss-alps-guetzli.jpg 526K

Command: guetzli --quality 85 swiss-alps-guetzli.jpg swiss-alps-guetzli.jpg
Example Output: (none)

Execution Time: ~4m

Interestingly, doing a Guetzli optimisation from the original image takes a little longer (~5 mins), but results in a 10k smaller file size - so the ultimate smallest file size is 516k.

See if you can determine the difference in visual quality for yourself - I cannot, and the download an file size is half the original, or twice as fast. For Photography and Creative blogs, this is nearly always a worthwhile investment of time for a modest number of images.

Guetzli Optimised Image, From Original: swiss-alps-guetzli-from-orig.jpg 516K swiss-alps-guetzli.jpg 521K

Initial testing after doing the above suggests the resolution of the native image (originally 3000x1716px) was going to be “down scaled” within my CSS code to a display resolution of 775x743px, or 93% larger (including to be downloaded) than it needs to be. So let’s initially convert it to the correct dimensions natively:

convert swiss-alps.jpg -resize 775x743 swiss-alps-resized.jpg

Then, applying the optimisations above, these are the results.

Pulling it together with some BASH script

OK now we’ve identified a list of JPEGs that are worthy of burning some CPU cycles to optimise using Guetzli.

Let’s resize them first -

#!/bin/bash

# Usage: ./this-script.sh image-name.jpg 200x400(new desired resolution)
# Example: ./img.sh IMG_8749.jpg 267x355

# First take a backup to a hidden dot file with a tilde ~ "just in case"
cp $1 .$1~
# Next convert the image to the new resolution in place
convert $1 -resize $2 $1

Then let’s put them into a list file in ‘/tmp/list’, including their relative path to the current working directory, and use another script to iterate over them -

#!/bin/bash
while read image; do
  # List the original size
  ls -lash "$image"
  # Iterate using Guetzli, noting no output is expected
  guetzli --quality 85 "$image" "$image"
  # List the new improved size
  ls -lash "$image"
done </tmp/list