Headless SVG rendering part 2

I revisted headless SVG rendering and decided to stick with PhantomJS since I already have it working. It’s rendering text poorly and path strokes not at all, probably fixable with some upgrades that are inconvenient in Debian. But I can work around that for now.

Scripting PhantomJS turns out to be pretty easy. Here’s the Javascript program I use to drive it:

if (phantom.state.length == 0) {
    phantom.state = "rasterize";
    phantom.viewportSize = { width: 64, height: 64 };
    phantom.open("vis-phantom.html");
} else {
    phantom.render("out.png");
    phantom.exit();
}

Unfortunately the input and output filenames are hard-coded. Phantom has command line argument support but I can’t figure a way to get that all the way into my HTML file (to load a specific script), so I just went with a hardcoded input file named data.js.

Here’s my shell script to render a PNG, crop it, and optipng crush it. The crop shouldn’t be necessary, but for some reason I’m ending up with 3 pixels below my SVG element.

set -e
# Render a wind rose image for the given datafile
input="$1"
output="${1%.js}.png"

# remove old crap
rm -f data.js out.png cropped.png "$output"
# Symlink the data to the expected place
ln -s "$1" data.js

# Render, crop, and crush
phantomjs/bin/phantomjs render.js
convert out.png -crop 64x64+0+0 cropped.png
optipng -force -quiet -preserve -out "$output" cropped.png

# clean up
rm -f data.js out.png cropped.png

It takes about 300ms to render a single image for my simple SVG based graphics.