NodeJS Add Text To Image (Simple Examples)

Welcome to a tutorial on how to add text to an image in NodeJS. In client-side Javascript, we can use the native Canvas API to write text on an image. Thankfully in NodeJS, we also have a canvas library to simulate that – Read on for the examples!

 

 

TABLE OF CONTENTS

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

 

NODEJS ADD TEXT TO IMAGE

All right, let us now get into the examples of adding text to an image in NodeJS.

 

QUICK SETUP

Run npm i express canvas to install the required modules.

 

1) SIMPLE ADD TEXT TO AN IMAGE

1-simple.js
// (A) LOAD MODULES
const fs = require("fs"),
      { createCanvas, loadImage } = require("canvas");
 
// (B) SETTINGS
const
sFile = "demo.png",   // source image
sSave = "demoA.png",  // "save as"
sText = "FRIED RICE", // text to write
sX = 80, sY = 80;     // text position
 
// (C) LOAD IMAGE + DRAW TEXT
loadImage(sFile).then(img => {
  // (C1) CREATE CANVAS
  const canvas = createCanvas(img.width, img.height),
        ctx = canvas.getContext("2d");
 
  // (C2) DRAW IMAGE ONTO CANVAS
  ctx.drawImage(img, 0, 0);
 
  // (C3) WRITE TEXT ONTO IMAGE
  ctx.fillText(sText, sX, sY);
 
  // (C4) SAVE
  const out = fs.createWriteStream(sSave),
        stream = canvas.createPNGStream();
  stream.pipe(out);
  out.on("finish", () => console.log("Done"));
});

For you guys who are somehow lost, it’s easier to focus on section (C) only:

  • (C) Load the image first.
  • (C1) When the image is loaded, create an empty canvas.
  • (C2) “Copy” the entire image onto the canvas.
  • (C3) Then write the text on top.
  • (C4) Finally, save the canvas as an image file.

 

 

2) MORE TEXT OPTIONS

2-more.js
// (A) LOAD MODULES
const fs = require("fs"),
      { createCanvas, loadImage } = require("canvas");
 
// (B) SETTINGS
const
sFile = "demo.png",   // source image
sSave = "demoA.png",  // "save as"
sText = "FRIED RICE", // text to write
sX = 80, sY = 80;     // text position
registerFont("C:/Windows/Fonts/arialbd.ttf", { family: "Arial Bold" }); // CHANGE TO YOUR OWN!
 
// (C) LOAD IMAGE + DRAW TEXT
loadImage(sFile).then(img => {
  // (C1) CREATE CANVAS
  const canvas = createCanvas(img.width, img.height),
        ctx = canvas.getContext("2d");
 
  // (C2) DRAW IMAGE ONTO CANVAS
  ctx.drawImage(img, 0, 0);
 
  // (C3) WRITE TEXT ONTO IMAGE
  ctx.font = '36px "Arial Bold"';
  ctx.fillStyle = "rgba(255, 0, 0, 0.4)";
  ctx.lineWidth = 2;
  ctx.strokeStyle = "rgb(0, 0, 0)";
  ctx.fillText(sText, sX, sY);
  ctx.strokeText(sText, sX, sY);
 
  // (C4) SAVE
  const out = fs.createWriteStream(sSave),
        stream = canvas.createPNGStream();
  stream.pipe(out);
  out.on("finish", () => console.log("Done"));
});

As you can see, the above text is nearly illegible and needs some improvements. There are quite a number of ways we can work with the text, and here are a few of the common ones:

  • To use a custom font:
    • (B) We have to registerFont() first – Remember to change this to your own.
    • (C3) Use ctx.font to specify the font size, font weight, and font family.
  • To set transparent text, use ctx.fillStyle = "rgba(R,G,B,A)".
  • To stroke (outline) the text:
    • Use ctx.lineWidth to control the thickness.
    • Use ctx.strokeStyle to control the outline color and opacity.
    • Draw the outline using ctx.strokeText().
    • Take note, strokeText() will only draw the outline. It is necessary to call fillText() if you want to fill in the text.

 

 

3) CENTER TEXT ON IMAGE

3-center.js
// (A) LOAD MODULES
const fs = require("fs"),
      { registerFont, createCanvas, loadImage } = require("canvas");
 
// (B) SETTINGS - CHANGE FONT TO YOUR OWN!
const
sFile = "demo.png",   // source image
sSave = "demoC.png",  // "save as"
sText = "FRIED RICE"; // text to write
registerFont("C:/Windows/Fonts/arialbd.ttf", { family: "Arial Bold" }); // CHANGE TO YOUR OWN!
 
// (C) LOAD IMAGE + DRAW TEXT
loadImage(sFile).then(img => {
  // (C1) CREATE CANVAS + DRAW IMAGE
  const canvas = createCanvas(img.width, img.height),
        ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
 
  // (C2) TEXT DIMENSIONS
  ctx.font = '36px "Arial Bold"';
  ctx.fillStyle = "rgba(255, 0, 0, 0.4)";
  ctx.lineWidth = 2;
  ctx.strokeStyle = "rgb(0, 0, 0)";
  let td = ctx.measureText(sText),
      tw = td.width,
      th = td.actualBoundingBoxAscent + td.actualBoundingBoxDescent;
 
  // (C3) CALCULATE CENTER & WRITE ON CENTER
  let x = Math.floor((img.naturalWidth - tw) / 2),
      y = Math.floor((img.naturalHeight + th) / 2);
  ctx.strokeText(sText, x, y);
  ctx.fillText(sText, x, y);
 
  // (C4) SAVE
  const out = fs.createWriteStream(sSave),
        stream = canvas.createPNGStream();
  stream.pipe(out);
  out.on("finish", () => console.log("Done"));
});

Lastly, centering the text is unfortunately Mathematical.

  • (C2) Define the “text settings” as usual, then use ctx.measureText() to get the text box dimensions.
  • (C3) To calculate the center XY coordinates:
    • X = FLOOR((IMAGE WIDTH - TEXT WIDTH) ÷ 2)
    • Y = FLOOR((IMAGE HEIGHT + TEXT HEIGHT) ÷ 2)

 

 

EXTRAS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

A COUPLE OF ISSUES…

  • The Node Canvas library does not support WEBP at the time of writing. You can try using Sharp to convert the image file format.
  • There’s some funny custom font issue in Windows. The font has to be installed in Windows, or the script will throw an error.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *