Creating thumbnails using PhantomJS and ImageMagick

Frederic Cambus March 18, 2012 [JavaScript]

As some people asked for more information about how I render thumbnails for NodeCloud, I decided to document the process and post about it, so here we go.

In order to take the screenshots, I'm using a simplified version of the rasterize.js file bundled with PhantomJS, configured with a viewport size of 1024x768 and modified to wait 2000 milliseconds before creating output file, in order to allow every page element sufficient time to render.

Here is the script:

var page = new WebPage(),
    address, output, size;

if (phantom.args.length < 2) {
    console.log('Usage: rasterize.js URL filename');
    phantom.exit();
} else {
    address = phantom.args[0];
    output = phantom.args[1];

    page.viewportSize = { width: 1024, height: 768 };

    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
        } else {
            window.setTimeout(function () {
                page.render(output);
                phantom.exit();
            }, 2000);
        }
    });
}

To rasterize a given page, we call the previous script as follow:

phantomjs --load-plugins=yes rasterize.js https://www.nodecloud.org nodecloud.org.png

Now, the second part of the process is creating a thumbnail using ImageMagick:

convert "nodecloud.org.png" -crop 1024x768+0+0 "nodecloud.org.png"
convert "nodecloud.org.png" -filter Lanczos -thumbnail 200x150 "nodecloud.org-thumbnail.png"

This is done in two steps: first we crop the top of the output rendered by PhantomJS in order to get a 4:3 ratio image, and then we resize it using the Lanczos filter.

We can easily automate the process to convert a batch of sites using a simple Bash script defining an array containing a list of URLs to generate thumbnails from:

#!/bin/bash

sites=( cambus.net nodecloud.org )

for site in "${sites[@]}"
do
	echo "- Processing: $site"
	phantomjs --load-plugins=yes rasterize.js http://$site $site.png
	convert "$site.png" -crop 1024x768+0+0 "$site.png" && convert "$site.png" -filter Lanczos -thumbnail 200x150 "$site-thumbnail.png"
	echo "- Done processing: $site"
done

Lastly, I would recommend using the excellent OptiPNG to optimize thumbnails file size.