26

I'm trying to create a simple dynamic-badge (png) to embed in static pages to let know the status of my application.

I'd like so to use an existing PNG image and write on it some text with Node.js.
I've found lot of libraries but all of them use Imagemagick or Cairo as native dependencies, I'd like to avoid to install anything else on the server.

I've then found lwip, but I can't really understand how to write text on an image with it. How can I do?

Fez Vrasta
  • 14,110
  • 21
  • 98
  • 160
  • 2
    As an alternative, would you consider wrapping the PNG in an SVG and add your text that way? My answer [here](http://stackoverflow.com/questions/24413133/batik-put-svg-on-top-of-image/24413676#24413676) shows the basics of this approach. – Robby Cornelissen Oct 10 '14 at 07:29
  • svg is not supported by old browsers so I don't think would be an enough cross browser solution... – Fez Vrasta Oct 10 '14 at 07:30
  • 1
    I see your point. The question is then, how far back do you want to go in your browser support? PNG is not supported in old browsers either... You could also render the SVG back to PNG using e.g. https://www.npmjs.org/package/svg2png – Robby Cornelissen Oct 10 '14 at 07:32
  • yes but it's much more supported than svg – Fez Vrasta Oct 10 '14 at 07:36
  • You're right, of course. – Robby Cornelissen Oct 10 '14 at 07:38

2 Answers2

34

You could use Jimp. It has a print method:

var Jimp = require("jimp");

var fileName = 'test.png';
var imageCaption = 'Image caption';
var loadedImage;

Jimp.read(fileName)
    .then(function (image) {
        loadedImage = image;
        return Jimp.loadFont(Jimp.FONT_SANS_16_BLACK);
    })
    .then(function (font) {
        loadedImage.print(font, 10, 10, imageCaption)
                   .write(fileName);
    })
    .catch(function (err) {
        console.error(err);
    });
Damian
  • 2,752
  • 1
  • 29
  • 28
xstephen95x
  • 449
  • 4
  • 3
  • 1
    Or, it looks like everybody supports SVG these days: http://caniuse.com/#feat=svg – David T. Macknet Aug 08 '16 at 21:13
  • 2
    With Jimp you cannot write text with any size and color. – dumitru Aug 22 '17 at 16:53
  • @dumitru You can. – Rodrigo Leite Aug 30 '17 at 16:15
  • Can we add a rectangular overlay on the top and text inside the overlay? with JIMP? – johnny Oct 02 '17 at 19:25
  • 7
    The limitation I have fount with Jimp is that you MUST use bitmap images and it is non-trivial to go from a ttf to a fnt file. – Victorio Berra Jan 25 '18 at 16:22
  • 1
    @VictorioBerra , you mentioned that ttf to fnt file is non-trivial . well, I am trying that from yesterday, and haven't been able to do it. https://stackoverflow.com/questions/24529369/how-to-convert-ttf-to-fnt-with-fontforge I am following this link, but still no help. – Neer Patel May 20 '18 at 16:54
  • Im also looking for custom Fonts and a Square Border around the printed words, as well as word wrapping. Anyone has a suggestion for the Square border? – omarojo Sep 11 '18 at 19:24
  • Jimp is using 30% of my server CPU when trying to just place a text on the image. I've a 4 core CPU. If 5 users tries to run my code at the same time the server goes down. – Renan Coelho Jul 25 '22 at 19:51
1

If you want to use a ttf file you can use gm This will also align the text automatically so you don't have to keep track of your letter sizing / location.

const gm = require('gm').subClass({imageMagick: true});


gm('path/to/image.png')
        .fill("#FFFFFF")
        .font("./font.ttf", 20)
        .drawText(15, 10, "your text", 'southeast') //can be any location
        .write("./output.png", function (err) {
            if (!err) console.log('done');
        });
Daniel
  • 2,223
  • 3
  • 9
  • 18