Let's continue the topic of reducing file sizes started with the previous post and talk about making images smaller.
Engineer's guide to smaller images
Just to set the frame of the discussion - this is not about using Photoshop or setting the quality of the JPEGs and so on. I realize that we, web developers, wear many hats - we're designers, client/server coders, Apache/Linux admins, database heros. But this post is not about using image programs and assumes that you or your designer has already created the images to be used on the site with the appropriate colors, quality and so on.
Now, repeat after me: you should never take an image from the designer and put it up on the web.
Most often this image is bigger than it should be. It's not the designer's fault, it's usually the software used to produce the image.
You shouldn't put an image up on your server before running it through a few tools. These tools are free, open source, cross-platform and can be run on the command line, hence scripted and run in batches over a large number of files - by you, or even better, automatically by a build deployment process. It's OK to batch-run those files without human intervention, because these tools simply optimize the files, they don't change the pixel information, so the "after" images look exactly like "before", only smaller.
Selecting the right file format
The first step towards leaner images is to select the correct file format. There are three options:
- JPEG for photos. Photos contain millions of colors and smooth transitions of colors. Blue skies, clouds, sunset, your dog, lolcats - all photos.
- GIF is for the occasional "loading..." progress animation. This is it, no other uses for GIFs.
- PNG is for everything that's not a photo or an animation. That includes all icons, graphs, buttons, gradients, and what not. Any image with sharp transitions of colors. Think (but don't use for) text. Sharp transitions become "dirty" in JPEG.
PNG is an interesting topic for a follow up post, for now let's stop here. If it's not a photo, it should be PNG. An edge case is a screenshot for example. Depends on what's on the screen of course, but most often JPEG will give a smaller size if you can live with the artifacts around the sharp edges (like text).
Unfortunately many people still use GIFs even for non-animated images. That's a mistake. PNG is a superior format and yields smaller file sizes.
People still use GIFs because they think either that a/ GIF is smaller than PNG or b/ there's lack of support for PNG in browsers. These are misconceptions and I'll talk more about them tomorrow.
So, the way to optimize a GIF is to convert it to PNG.
# option 1: ImageMagick (if you know the filename) $ convert logo.gif logo.png # option 2: ImageMagick again (if you just convert all files in a directory) $ mogrify -format png *.gif # option 3: OptiPNG $ optipng *.gif
These are just some of the options, I'm sure there are others.
After the conversion you can optimize the new PNGs like all other PNGs
There are various ways to write a PNG file. Unfortunately not all image editing programs do a good job at writing PNGs for the minimal file size.
Luckily, to fill the void, there's a great number of tools that excel in writing small PNGs. There are different ways to optimize a PNG:
- Stripping out "chunks" - PNG is an extensible format. Extensions come in the form of chunks and most chunks are not needed for the web.
- Reducing the number of colors and switching between PNG types - truecolor PNG, grayscale, palette...
- Chosing the best "filter". Filters are a pre-compression step. You can compress any type of file, but when you know the file is an image, you can do better. Filters are for this purpose.
- Optimizing the actual DEFLATE compression algorithm
Different tools specialize in one or more of these areas. So the more tools you run, the better the results will be. But you have to run at least one tool, always. You'll be surprised how unoptimized are most PNGs coming from common commercial image programs.
So, to optimize a PNG you shoul run as many of the following programs as possible:
# optipng (skip -o7 to run faster) $ optipng -o7 my.png # pngcrush (skip -brute to run faster) $ pngcrush -rem alla -brute -reduce my.png my.png.temp $ mv my.png.temp my.png # pngout - closed source, non-windows binaries here # (add parameter -s2 to run faster) $ pngout my.png # advpng (use -z2 to run faster) $ advpng -z4 my.png # deflopt - windows only $ deflopt my.png
Other tools to note include PNGrewrite, PNGNQ and PNGquant, but they are limited because they deal only with PNG8 (256 colors) files. PNGNQ and PNGQuant are actually converters from truecolor to PNG8, so they are not guaranteed to be lossless. PNGreqwrute is safe to use, it will just silently fail if the file has more than 256 colors, so there's nothing to lose.
Oh, and another, excellent tool - PNGOptimizer, windows-only has both command line interface and a GUI.
PNGSlim for the hardcore PNG optimization
If you're really serious about optimizing your PNGs, the tool is called PNGSlim. It's a Windows-only batch file that runs pretty much all tools above and runs them (especially PNGOut) with all kinds of parameters, hundreds of times. So it can take a while to run.
JPEG is a lossy format (you lose information every time you save it, even if you choose 100% quality), but there are some operations that can be done losslessly - such as tweaking comments and meta information, cropping, rotating to 90, 180, 270 degrees. The tool that does this magic is called JPEGTran and is likely already on your unix/linux box. If not - here's how to install it (for Windows - get the .exe here)
So to optimize a JPEG losslessly you remove the meta information and optimize the so called Huffman tables. For bigger JPEGs (bigger than 10K) you can also convert the image to progressive coding.
# strip meta and optimize $ jpegtran -copy none source.jpg > destination.jpg # strip meta and convert to progressive coding $ jpegtran -copy none -progressive source.jpg > destination.jpg # keep all meta but still optimize $ jpegtran -copy all source.jpg > destination.jpg
Important note on stripping meta
Only strip meta information from images you own the rights for and have permission. Otherwise you're committing a crime. Photographers put important copyright information in meta markers.
Optimizing GIF animations
Remember - no GIFs other than animations. For animations, run GIFsicle ( ?? ) berfore you put them up:
# GIFSicle $ gifsicle -O2 source.gif > destination.gif
These are the core tools for image optimization. There's a number of wrapper tools that are more or less UIs on top of these, because there are people who don't like consoles (really?!). I'll list the few that I can think of, please comment if you know of others, especially for windows. It's nice to give nice UIs to give to designers so they can drag-drop optimize images too.
- smush.it, created by yours truly and Nicole Sullivan, now part of YSlow - runs pngcrush, jpegtran, gifsicle
- PageSpeed runs optipng, jpegtran
- PunyPNG - originally inspired by smush.it, but more advanced
- ImageOptim - Nice easy UI for Mac, runs most of the tools above (hope your company firewall doesn't block the site because of the domain name ;))
- PNGSquash another UI for Mac, runs advpng, pngcrush, optipng
- PNG Monster is for Windows, runs many PNG tools, you can drag/drop on it
- IrfanView - my favorite image viewer for Windows has a plugin to use PNGOut
- WP-Smushit is a WordPress plugin by Alex Dunae which sends all your image uploads to smush.it for optimization. Talk about easy!
Series of articles on YUIBlog:
- Image Optimization - 7 mistakes
- Image Weight Loss Clinic - a 5-minute "ignite" case study of optimizing a web site. Spoiler: 30.15% image size reduction. Transcript here.
- Derek Tonn's graphics optimization blog
- Sergey Chikuyonok's excellent articles on optimizing PNGs and optimizing JPEGs
- Installing PNG tools on the Mac
- The book "Even Faster Web Sites" has a chapter written by yours truly and Nicole Sullivan
Thank you for reading. Now you have a whole lot of tools/toys to install and play with. Image optimization is an easy way to improve performance, it's just running a bunch of tools. You don't need to worry that the quality will suffer (so the designer won't be disappointed in you :)). So you can only win. You may win quite a bit, you may win just a little (anywhere between 5 to 30% savings is what I've seen on random live sites when I was working on and testing smush.it). The thing is you'll almost always win something.
And because it's human to forget to optimize the images before you push them live, do take the time to setup the optimization step as part of the automated deployment process.
And to summarize once again the steps of what this automated process would be:
- Convert GIFs to PNG. Then relax and take a deep breath (instead of flaming the unfortunate soul who created the GIFs) while you string replace "gif" with "png" in all your styleshets
- Run PNGs through optipng, pngcrush, pngout, any or all of the tools listed above
- Run JPEGtran
- Run GIFsicle