Screenshots of any size, with PhantomJS

The problem

Sometimes we need a screenshot of a web page with a different resolution of our own screen. If the resolution is lower than our screen, the thing can be done. Just resize the window to the desired size and use one of the many plugins available, although, sometimes, they aren’t very reliable if we want an accurate resolution. If the resolution is bigger, it becomes a bit more complicated. If we need to simulate a higher pixel density (aka retina), even worse.

I came across this problem when I needed to create screenshots for my portfolio. I bought one of those .psd files with computers and mobile phones of various sizes. For some reason, all these files depict Apple products, and to function properly, needed screenshots with a resolution identical to that of Macs and iPhones.

The solution

This is where PhantomJS comes in. An implementation of Webkit that can be manipulated via Javascript. It has several use cases. Among them, the one that interests us today, generating screenshots.

The script to do this is quite simple.

var webPage = require('webpage');
var page = webPage.create();

// the size of the screenshot 
page.viewportSize = { width: 2880, height: 1800 };

// the url of the page to capture 
page.open("http://zecipriano.com/", function start(status) {

    page.evaluate(function () {

        // the scale of the content, 1 for normal, 2 for a kind of retina
        var scale = 2;

        document.body.style.webkitTransform = "scale(" + scale + ")";
        document.body.style.webkitTransformOrigin = "0% 0%";
        document.body.style.width = 100/scale + "%";

    });

    // the file to save the screenshot, the extension defines the format
    page.render('output.png');

    phantom.exit();

});

To get a screenshot just write this script in a file (for example screenshot.js), edit the desired values ​​and run PhamtonJS.

phantomjs screenshot.js

The scale = 2 is the value that will simulate a screen density of 2x (kind of, see notes). For a normal screenshot, the value should be 1.

Note that this is just a simple and dirty way to solve the problem. The script could be improved in several ways, including accepting parameters instead of hardcoding the values into the script.

Some questions:

  • The scale = 2 does not emulate completely a high density screen. It just doubles the size of the content, the device pixel ratio remains 1, which eliminates, for example, the possibility of generating a screenshot of a smartphone screen correctly.
  • The current version (1.9) does not support Google Web Fonts (more specifically .woff files). The next version (2.0) solves this problem. You can find a build of version 2 here.
  • The height of the viewport appears to have no influence on the height of the screenshot. But after the screenshot is generated it’s easy to cut to the correct size.