1

I want to generate and serve an image of text.

At the moment I'm trying to use text2png:

text2png('this string', {font: '14px Courier', bgColor: 'white'}) 

But text2png doesn't seem to be able to do unicode/emoji.

It's turning 🔥 into  enter image description here  and chinese characters, e.g. 中文, into  enter image description here.

Is there a way I can render strings containing these kinds of characters into images?

text2png was working perfectly in other respects.

3
  • Just render the text on a canvas and use getImageData Commented Feb 17, 2018 at 16:26
  • @C5H8NNaO4 I'm assuming that's what text2png does Commented Feb 17, 2018 at 16:34
  • Supposedly. Maybe they escape the unicode characters Commented Feb 17, 2018 at 16:48

1 Answer 1

2

text2png can't do this at the moment.

It depends on node-canvas, which in turn depends on cairo. Cairo's stable version as of writing this (1.14.12) doesn't seem to support emoji.

However, the development version of cairo (1.15.8) supports emoji.

Features and Enhancements

  • Support colored emoji glyphs, stored as PNG images in OpenType fonts.

So maybe building and trying to force node-canvas to use this later version of cairo would work out.


For now, I found this package wkhtmltox. It turns HTML into images (or PDFs, but I won't use that).

Make sure you have the command-line tool wkhtmltoimage installed as well. The node.js package wkhtmltox depends on it for image-generation. (We don't care about wkhtmltopdf).

Pop all your text into some external HTML document, ./content.html:

<!doctype html> <html> <head><meta charset="utf-8"></head> <body> Here's some 中文 letters! </body> </html> 

Then to render this:

const fs = require('fs'); const wkhtmltox = require('wkhtmltox'); const converter = new wkhtmltox(); converter.image(fs.createReadStream('content.html'), { format: "png" }) .pipe(fs.createWriteStream('image.png')); 

We're piping the PNG buffer here, you can also pipe to HTTP response objects (well, any writeable stream).

wkhtmltox will render everything like a browser would, as far as I can tell (even supporting styles etc.), as long as you have the fonts installed.

So make sure you have a font with Chinese glyphs installed.

I haven't tested with emoji myself, but I assume it will work as long as you have the correct fonts.

Sign up to request clarification or add additional context in comments.

5 Comments

Wish I'd known you went through all this already before I spent time trying to write out nice directions for you... anyway, reason I know so much about setup is because I wrote gen-pdf, but unfortunately that won't help you with this.
@PatrickRoberts yeah I noticed, I guess you've been detailing the set-up for node canvas and porting C5H8NNaO4's answer? From what I've researched it looks like it would work on newer builds of cairo, but I don't feel completely comfortable setting all of that up. I actually found this solution a while ago and just remembered to come back to this question to share. It's not ideal (wkhtmltoimage is a bit slow) but it's working for me atm.
Maybe in a year a direct port of C5H8NNaO4's solution to node may just work, who knows
I already have it set up on this machine, I had just written a quick test script to see if the other answer worked out of the box. It didn't. As I said, I have no idea if registerFont() would even work or not, on the newest build even.
It's an interesting problem anyway, I had some fun working on this the last couple days. Was doing on some linux box with like no fonts, and faffing around with installing chinese fonts and all of it was quite educational xD