After colorizing the SVG icons I needed to create images suitable for CSS sprites out of them. The first step is rasterizing the SVG files, as I described in the previous article.
We now have a bundle of PNG files, which lay around and wait to be joined in one single image. Fortunately, the command line cure for this problem is clear. It’s called ImageMagick.
The following small script does the needed magic. Let’s go through it line by line.
ICONIDS=$(sed -n '/id=/p' icons.svg | grep transform= | \
sed 's/.*id="\([^"]\+\)".*/\1/')
for item in $ICONIDS; do
montage -background transparent -tile 1x7 -geometry 24x24 \
bookmark/static/$item.e60042.png \
NULL: \
bookmark/static/$item.ffffff.png \
NULL: \
bookmark/static/$item.95002b.png \
NULL: \
bookmark/static/$item.ff9fbc.png \
bookmark/static/$item.uncrushed.png
pngcrush -b bookmark/static/$item.uncrushed.png bookmark/static/$item.png
done
The SVG file is marked up with the following assumption holding: Each
icon has an attribute id="icon name"
and the
attribute transform
. (The later is used to translate the
icon away from (0,0)
for better viewing in SVG editors.)
Both attributes are on the same line. (In general this is a strong
assumption for an XML file, but in this case it’s useful.)
Then the first line filters out all icon IDs. Find all lines with an
attribute id
, filter them for lines with the attribute
transform
and finally print only the ID. Store the result
in ICONIDS
.
The for
loop goes through all icons. We will create a sprite image for
each of these IDs. I assume, that there are four images per ID already ready: <ID>.ffffff.png
is the white icon <ID>
, <ID>.e60042.png
the dark-red and so on.
The magic happens in the call to montage(1)
. The sprite components
should be separated by one empty tile between each color, because the HTML element,
where the sprite is applied, is higher than the icon height.
I achieved this with the combination of -geometry 24x24
, which
sets the tile dimensions, and the NULL:
pseudo-image, that ImageMagick
uses in cases, where no real image data is there.
So the call to montage
simply joins the images in the given order,
with empty space, where a NULL:
stands. The result wanders into
<ID>.uncrushed.png
.
Finally we use pngcrush(1)
to reduce the file size of the generated
sprite images. The -b
switch lets pngcrush
try with
brute force to find optimal reduction.
É voila! Ready are our CSS sprites. Now, if we find an error
in the SVG source, it’s a matter of one Makefile
rule to regenerate all
buttons.