Drawing and saving image using node-canvas package

The node-canvas package is a NodeJS module allows you to create an image programatically. The package uses Cairo 2D graphics library so that you can generate an image in many common formats like JPG, JPEG or PNG.

The package also mirrors the HTML <canvas> element implementation, so you will quickly understand node-canvas if you already understand how to draw images using HTML <canvas> element.

To start using the package, you just need to install it from npm with the following command:

npm install canvas
# or
yarn add canvas

Once installed, you can start drawing an image by writing JavaScript code. First, you need to require the createCanvas() method from the module as shown below:

const { createCanvas } = require("canvas");

Then, create a new canvas and pass the width and height of your canvas as required. This will be the size of your image output later.

The following example will create a canvas of 1200 X 620:

const { createCanvas } = require("canvas");

const width = 1200;
const height = 620;

const canvas = createCanvas(width, height);

Once the canvas is created, retrieve the context of the canvas by using the getContext() method:

const context = canvas.getContext("2d");

You can add texts, colors, or images to the context so it will be generated to the output image. Let’s start by adding yellow background color to the image by using the fillRect() method:

context.fillStyle = "yellow";
context.fillRect(0, 0, width, height);

To generate the image, you need to transform the canvas to a buffer that can be written to an output using the toBuffer() method:

const buffer = canvas.toBuffer("image/png");

Finally, you just need to write the output using fs.writeFileSync() method:

const fs = require("fs");
fs.writeFileSync("./image.png", buffer);

An image named image.png will be generated in your current folder. This image will be a blank image with yellow color:

To customize the image further, you can try to add text to the image using the following syntax:

context.fillStyle = "#000";
context.font = "72px Arial";
context.textAlign = "center";
context.fillText("Hello, World!", 400, 120);

The fillStyle property will set the color of the text to black, while thefont property sets the font size and font family. You can also set the text alignment to "center". Finally, you get the text written on the canvas using fillText property.

With that, the text "Hello World!" will be printed to the image output:

Next, let’s add an image to the canvas to make it look better. I’m going to add a NodeJS logo to the image, but you’re free to change it later with any image. First, draw a white rectangle to the canvas right where the the logo will be placed:

context.fillStyle = "#fff";
context.fillRect(400, 200, 300, 200);

Next, you need to grab the loadImage() method canvas as shown below:

const { createCanvas, loadImage } = require("canvas");

The loadImage() method requires a relative path to the image. It will return a Promise object for when the image has been successfully loaded, so you need to add a callback function inside .then chain to the method as follows:

loadImage("./NodeJS.png").then((image) => {
  context.drawImage(image, 425, 225);
});

When the image is loaded, use the drawImage() method to render the image in the canvas. To render the output after the image has been drawn, you need to place the writeFileSync() method inside the promise function callback:

loadImage("./NodeJS.png").then((image) => {
  context.drawImage(image, 425, 225);
  const buffer = canvas.toBuffer("image/png");
  fs.writeFileSync("./image.png", buffer);
});

The final output will be as follows:

And that’s how you can generate an image output using node-canvas package. You can view the full code for this project in the GitHub repository.

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.