Batch PNG Optimization

When designing web sites, squeezing your design down to as few kilobytes as possible is a critical operation to keep your site responsive to visitors with low-bandwidth internet connections.

In a well designed web site, markup is almost insignificant in size relative to the image files that make up a visually rich presentation. In order to create image files that are as tiny as possible, I use Ken Silverman‘s PNGOUT utility.

While PNGOUT serves my purposes very well, it has two flaws:

  1. No batch operation
  2. No support for FreeBSD

Fortunately, I can do something to address the first issue.

Below is a perl script I just finished pounding out. Given a base directory and optionally, custom pngout arguments, this script will recursively traverse through all subdirectories optimizing the PNG images via the pngout utility.

#!/usr/bin/perl

use strict;
use warnings;

use Cwd;

my $pngoutpath = "/usr/local/bin/pngout";

if (@ARGV == 2) {
	recurseDir ($ARGV[0], $ARGV[1]);
} elsif (@ARGV == 1) {
	recurseDir ($ARGV[0], 0);
} else {
	print "Usage: recursive-pngout dir [args]\n";
}

sub recurseDir
{
	my ($curpath, $args) = @_;

	if (opendir (CURDIR, $curpath)) {
		chdir ($curpath);

		my @files = readdir(CURDIR);
		closedir (CURDIR);

		foreach my $file (@files)
		{
			next if $file eq ".";
			next if $file eq "..";

			recurseDir ($file, $args);
		}

		chdir ('..');
	} else {
		if ($curpath =~ /.png$/) {
			my $dir = getcwd;

			if ($args) {
				system ("$pngoutpath $args $dir/$curpath");
			} else {
				system ("$pngoutpath $dir/$curpath");
			}
		}

		return;
	}
}

I know this could have been accomplished by a shell one-liner, but my abilities with the shell are a little rusty. I also tend to think in perl when I’m tackling a quick solution to a problem.

Leave a Reply