Using Canvas in Node JS
Have you ever wanted to generate dynamic images on the server side? With Node Canvas, it's easy! Node Canvas is a module that allows you to use the canvas element on the backend, making it simple to create images based on user input.
Node Canvas is a module that allows you to use the canvas element on the server side for generating dynamic images. You can see an example of this by going to the URL below and replacing test-image
with any text to get a random image.
1https://decode.sh/hero/Test%20Image
Installation
1npm install canvas
Note: canvas uses Cairo, a 2D graphics library with support for multiple output devices, which you may need to install in order to get canvas working properly. Use the table below to install.
OS | Command |
---|---|
OS X | Using Homebrew: brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman |
Ubuntu | sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev |
Fedora | sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel |
Solaris | pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto |
OpenBSD | doas pkg_add cairo pango png jpeg giflib |
Windows | See the wiki |
Others | See the wiki |
Mac OS X v10.11+: If you have recently updated to Mac OS X v10.11+ and are experiencing trouble when compiling, run the following command: xcode-select --install
. Read more about the problem on Stack Overflow.
If you have xcode 10.0 or higher installed, in order to build from source you need NPM 6.4.1 or higher.
Usage
To use canvas
, you will first need to import createCanvas
like this:
1import { createCanvas } from "canvas";
Creating the canvas is as simple as with the native module
1const canvas = createCanvas(width, height);
2const ctx = canvas.getContext("2d");
Example
Creating the canvas is as easy as with the native module. Here is an example from the official documentation that draws the word 'Awesome!' along with an image of a cat wearing a lime helmet:
1const { createCanvas, loadImage } = require("canvas");
2const canvas = createCanvas(200, 200);
3const ctx = canvas.getContext("2d");
4
5// Write "Awesome!"
6ctx.font = "30px Impact";
7ctx.rotate(0.1);
8ctx.fillText("Awesome!", 50, 100);
9
10// Draw line under text
11var text = ctx.measureText("Awesome!");
12ctx.strokeStyle = "rgba(0,0,0,0.5)";
13ctx.beginPath();
14ctx.lineTo(50, 102);
15ctx.lineTo(50 + text.width, 102);
16ctx.stroke();
17
18// Draw cat with lime helmet
19loadImage("examples/images/lime-cat.jpg").then((image) => {
20 ctx.drawImage(image, 50, 0, 70, 70);
21
22 console.log('<img src="' + canvas.toDataURL() + '" />');
23});
Exporting
To send the image to the client, you can use the non-standard API's in the documentation to convert the image to a buffer and return it in the Response object like this:
Svelte example
Using the same code as above, to send the image to the client all you have to do is convert the image to a buffer and return it in the Response
object.
Converting the canvas to a buffer
1canvas.toBuffer("image/jpeg");
Full code example
1import { error } from '@sveltejs/kit';
2import { createCanvas } from "canvas";
3
4export function GET({ params, url }) {
5 return new Promise((resolve, reject) => {
6 ctx.font = '30px Impact'
7 ctx.rotate(0.1)
8 ctx.fillText('Awesome!', 50, 100)
9
10 // Draw line under text
11 var text = ctx.measureText('Awesome!')
12 ctx.strokeStyle = 'rgba(0,0,0,0.5)'
13 ctx.beginPath()
14 ctx.lineTo(50, 102)
15 ctx.lineTo(50 + text.width, 102)
16 ctx.stroke()
17
18 // Draw cat with lime helmet
19 loadImage('examples/images/lime-cat.jpg').then((image) => {
20 ctx.drawImage(image, 50, 0, 70, 70)
21
22 resolve(new Response(canvas.toBuffer("image/jpeg")));
23 }).catch(() => {
24 throw error(404, 'Not found');
25 })
26}