How to optimize large image files for the web, the command-line way
I use Inkscape to draw all my vector graphics nowadays. Inkscape has a "Export Bitmap" feature (analogous to Photoshop/Illustrator's "Save For Web") that lets you export PNGs, but it's pretty basic (I assume by design).
But what do you do once you've got that 400k Twitter background .png file exported from Inkscape?
Or what if you want to do better than the image compression options in Adobe Photoshop or Illustrator, or even the GIMP?
Here are 2 decent options, assuming you're starting with a lossless PNG file:
Option 1: Shrinking the PNG into a smaller PNG
- optimize the PNG by throwing out unused data and reducing colors
- convert it to a lossy JPEG (hopefully not too lossy, eek)
GIF is not really an option now that PNG files are well-supported, unless you're making lovely dancing animated GIFs.
BMP? TGA? Other formats? These aren't good for web graphics. It's 2010, and web-suited bitmaps are JPG, PNG, GIF.
Side note: I hope vector formats like SVG will be more supported by web applications (e.g. as Twitter avatars and background designs) in the near future, but it's a steep uphill battle. I don't think it'll happen until cameras are capable of taking vector photos.
The starting image
Before trying either option, here's the image that I began with. This is the PNG that Inkscape generated via Export Bitmap:
I used OptiPNG to trim the useless data, shrinking my file from 389k to 318k. This step doesn't lose any image data.
$ sudo apt-get install optipng
$ optipng twitter_bg.png
In particular, OptiPNG trimmed the alpha data from my PNG, which didn't have any transparency. These were just wasted bytes.
Then, I used Pngnq to quantize the image. In other words, to decrease the number of colors in the image to an optimized smaller set of colors.
(Photoshop and Illustrator let you choose the number of colors in the "Save To Web" tool. Here we are doing the same thing manually.)
$ sudo apt-get install pngnq
$ pngnq -n 256 -s 1 -e b.png twitter_bg.png
The parameters I chose here are:
- -n 256: 256 colors, which is the max resulting palette in pngnq. Less than that would be too little to do my gradients justice.
- -s 1: Sample every pixel during its palette-picking algorithm. The default is 3, but I found that s=1 improved certain parts of my image drastically. The only drawback is a slightly longer wait (a couple seconds longer for my image).
Option 2: Converting the PNG to a JPEG, lossily
You can convert from PNG to JPEG using GIMP if you're more comfortable with a GUI than with the command line. You have less control over the way the result looks, but it's often good enough for web viewing purposes.
I don't know what's under the hood of the GIMP, and googling it for a few minutes didn't tell me. Supposedly resizing images downward in GIMP isn't as good as you can get with the right parameters in ImageMagick. But this is just a rumor. If I remember to look into it when I have some free time, I will. Who knows, GIMP might even be using ImageMagick for downscaling.
Anyhow, you probably have ImageMagick installed already (unless you're on Windows, then you probably want to install it through Cygwin), so just go ahead:
$ convert -compress JPEG -quality 87 twitter_bg.png twitter_bg.jpg
I found that 87% compression was the lowest I could deal with. But even that gave me a 187k image, and that was with enough blurriness to be mildly noticeable. Note the artifacts in the rainbow bands.
I'd rather give up colors and have zero blurriness than keep all the colors and have mild blurriness. Which is why I went with PNG color quantization in the end.
ImageMagick gives you a lot of other compression options. I tried compressing to various degrees using JPEG2000 rather than JPEG compression, but I didn't notice enough improvement one way or another. JPEG compression just looks bad when you're dealing with vector graphics or text. You need those crisp edges. Lossy JPEG is more of a photo type of compression.
Summary
There, I've written up as much as I could about the 2 options that were reasonable to me. Pick option 1 if you're dealing with bitmaps exported from Inkscape or other vector graphics.
But try option 2 if you're okay with some blurriness due to lossy compression artifacts.
Not all image compression is the same! It's worth experimenting with various image compression tools and libraries.
And if you try them all and still hope for better compression or quality, do some research on image compression algorithms and a little coding :)
Posted by Audrey M Roy