Render PDFs on the Server with PDF.JS and Node-Canvas

It occurred to me today that the new PDF.js library just makes calls into a canvas element on the document to render its content. So why couldn’t we change that to render directly to a node-canvas version of the canvas?

Turns out you can, and it’s really easy.

I made minor changes to pdf.js to get rid of the assumption of the browser, and added in a few Node.js specific requirements. In all the diff is less than a page.

Then I could just call pdf.js as though we had a local canvas. Here’s the code that works for me:

"use strict";

var Canvas = require('canvas');
var PDFJS  = require('./pdf.js');

var fs     = require('fs');

PDFJS.disableWorker = true;

fs.readFile(process.argv[2], function (err, data) {
    var data_array = new Uint8Array(data);
    PDFJS.getDocument(data_array).then(function (pdf) {
        pdf.getPage(1).then(function (page) {
            var scale = 1.5;
            var viewport = page.getViewport(scale);

            var canvas = new Canvas(viewport.width, viewport.height);

            var ctx = canvas.getContext('2d');
            page.render({canvasContext: ctx, viewport: viewport}).then(function () {
                console.log("Finished rendering?");

                var png = fs.createWriteStream('/tmp/test.png');
            }, function (err) {
                console.log("Got error: " + err.stack);



Performance isn’t terrible either – but I’d have to do more benchmarking to compare it to something like mupdf or xpdf for generating images from pages of PDFs

The big question is just on appearance – on the Mac I used it messes up the fonts a fair bit. This may be just issues with Cairo on the Mac, or it may be a more fundamental problem. I get much better results with mupdf at this time.


6 thoughts on “Render PDFs on the Server with PDF.JS and Node-Canvas

    • Unfortunately the code is lost at a previous company I worked at.

      Mostly it was a matter of searching for anything involving the DOM and commenting it out.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s