Losslessly Optimising existing JPEGs on your website(s) using jpegtran

Google recently announced that you can now use Webmaster Tools to track your site’s usability in mobile browsers. I checked a couple of my sites and the information given was wrong for both, so it seems to be pretty useless at the moment.

However, what they don’t mention is that their PageSpeed Insights has been updated to cover mobile (and desktop) usability. And testing some pages from the same sites I looked at in Webmaster Tools, the PageSpeed tool actually gives accurate information!

It’s well worth running a page from your site through the tool to see how it fares. Of course, you don’t have to follow all the suggestions it makes, but it may well point out an issue that you didn’t notice before. In my case it pointed out that many of my JPEG images could be losslessly optimised.

Other than removing the EXIF from the image (I guess that’s lossy, but it doesn’t affect the look of the image), I didn’t even realise that you could losslessly optimise images. While the Pagespeed tool will tell you how much you could save by optimising your images, unfortunately it doesn’t tell you what tool would give you that saving. The answer seems to be jpegtran.

jpegtran is a command line utility included with libjpeg, libjpeg-turbo, and mozjpeg. Mozjpeg can provide the best compression, but is quite a bit slower than libjpeg-turbo. A command line utility is very useful for optimising existing images on your websites, and I’ll cover that in a minute.

But it can also be helpful to have a nice GUI image compressor that you can run any new images through before you upload them to your site. For Windows you can try File Optimizer. While Mac users can use imageoptim. Both of these will optimise jpegs and pngs, and both make use of jpegtran for optimising jpegs. (Though in my tests File Optimizer didn’t work quite as well as libjpeg-turbo’s jpegtran, possibly it is using an older version or the libjpeg version).

For optimizing jpegs already on your websites, the easiest way to do this is to ssh into the server, then find all jpegs and run them through jpegtran. Of course, this assumes that you already have one of the libjpeg with the jpegtran utility installed.

For my own sites, I used the following commands:

find ./ -name "*.[Jj][Pp][Gg]" -exec bash -c '/path/to/libjpeg-turbo/bin/jpegtran -optimize -maxmemory 8M -copy none -outfile "$0" "$0"' {} \;
find ./ -name "*.[Jj][Pp][Ee][Gg]" -exec bash -c '/path/to/libjpeg-turbo/bin/jpegtran -optimize -maxmemory 8M -copy none -outfile "$0" "$0"' {} \;

That will first do a case insensitive search for .jpg files, starting in the current directory, and drilling down to all subdirectories, and putting each file it finds through jpegtran. I set the maxmemory parameter to 8M as I’m on shared hosting, and so need to ensure the RAM usage is kept low.

The second line does exactly the same thing, but for any files with a .jpeg extension. I would think it should be possible to do it all in one command, but I couldn’t work it out.

Basically, the command uses the find tool to find all jpg files. It uses the -exec parameter of find to execute a shell (bash). By passing -c as a parameter to bash, it will execute the next argument as a command, and any following arguments as positional parameters. When using find’s exec parameter, {} refers to the filename / path it has found, so we pass this to the bash command as a positional parameter. In the bash command we can then refer to this via $0.

By using $0 as the -outfile parameter value passed to jpegtran, as well as the file to be acted on, this ensures that jpegtran will overwrite each image with the optimised output. (The default for jpegtran is to send the optimised image to stdout, which wouldn’t be very helpful in this instance).

Note that jpegtran will strip any metadata from the file. If you want to keep the metadata, then you should use -copy all instead of -copy none.

I hope this helps if you’re looking to optimise your jpeg images in terms of filesize without increasing the level of lossy compression. If you have any suggestions, please do leave a comment below.

Posted on by xoogu, last updated

Leave a Reply