.

Tags:

PhantomJS is quite popular for headless testing of web applications. Because it packs real WebKit engine and it does not use any emulated implementation of DOM, CSS, Canvas, etc, PhantomJS can render a web page almost as good as what is expected from a web browser. This feature turns out to be quite useful to programmatically capture the content and save it as an image.

The simplest example of web page capture using PhantomJS is the following script. It is self-explanatory.

var page = require('webpage').create();
page.open('http://google.com', function () {
    page.render('google.png');
    phantom.exit();
});

A web service to capture web sites is something a lot of people would want to have. There are commercial solutions like url2png and websnapr to do that. If you want a DIY approach, this is however rather easy with PhantomJS. In fact, there are few ready-to-use screenshooting projects based on PhantomJS you need to look at, see the complete list for more info.

The working principle of such a project is dead simple. There is a front-end which deals with the API, i.e. handling the URL to be requested, the size of the preview, and so on. This will further kick a PhantomJS process which rasterizes the requested page. It is rather easy to construct and thus people have combined PhantomJS with anything from Node.js to Play2 framework.

For an online example of a screenshot project, take a look at Screener with its simplistic interface. Give it a try with your favorite web site and see how it handles it.

Since PhantomJS version 1.6 (Lavender), there are two additional features which can be useful for this screen capture purposes. The first one is zoom factor, implemented by Milian. By default it is 1, setting this value to 0.25 you will get the rendered web page in 25% zoom. This is really good if all you want is a thumbnail preview only. Another feature, this time coded by Ivan, is to output the rendering as base64 encoded image (preferably in PNG). This means, there is no need to save the capture into a temporary image file.

If we tweak our previous example to use these two features, the code would look like snippet. It will snapshot Google homepage, make it 4x smaller, and encode it as PNG in base64 straight to stdout.

var page = require('webpage').create();
page.open('http://google.com', function () {
    page.zoomFactor = 0.25;
    console.log(page.renderBase64());
    phantom.exit();
});

For some final inspiration, let’s see two projects which leverage the power of PhantomJS screen capture: Media Queries and ChromaNope.

mediaqueri.es from Eivind Uggedal is a collection of web sites with responsive design in mind. Every web page in the collection will be capture with a variety of viewport dimensions, thereby automating the look as if the page is visible on different mobile devices.

ChromaNope, built by Kris Hedges, is a simple web service which captures a web page and display it in 4 variants, normal and dichromacy: protanope, deuteranope, and tritanope. The goal is to simulate your sites for the color blinds. As Kris himself has written, “This helps designers make informed decisions about accessibility by identifying potential problems that color-blind users might have, problems that might have otherwise gone unnoticed.”

As an example, the following screenshot shows the look of PhantomJS web site, phantomjs.org, rendered by ChromaNope:

Last but not least, remember that PhantomJS on Linux is pure headless and therefore setting it up on a barebone Amazon EC2 instance is fairly painless (standard AMI or Ubuntu image should work). In fact, if you do not want the hassle of server management, use IronWorker, a service from Iron.io, to run your PhantomJS scripts with zero setup.

What do you want to capture today?

  • Anatoliy Kobzar

    does you use callbacks from page? some times i need to make async actions on page before take screenshot. i use timeout, but this is ugly.

    • http://ariya.ofilabs.com/ Ariya Hidayat

      Might be useful to discuss it in the mailing-list.

  • ankur

    if you don’t want to bother with setting up servers, worrying about storage/caching of images and general performance issues – you could just use an external service like urlbox.io to generate the screenshots for you

  • Julien

    @Anatoliy Kobzar Did you look at http://browshot.com/api/script ?