Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emoji to PNG or JPG in Node.js - how to?

For the project I'm working on I need to generate an image file from emoji (ideally Apple emoji). I thought it should be a fairly simple thing, but with each tool I use, I eventually run into a wall.

I've also considered working with an emoji set, like this one that I could query when needed. Unfortunately, the one I've linked to doesn't have Unicode 9.0 emoji such as avocado (🥑) shrimp (🦐) or harambe (🦍). Do you know of such an up-to-date set?

Code-wise, I've tried opentype.js, but it doesn't support .ttc fonts, which is the extension of the emoji font on my mac (Apple Color Emoji.ttc). I've converted the font to .ttf but that didn't work either:

  var opentype = require('opentype.js');
  opentype.load('./build_scripts/apple_color_emoji.ttf', function (err, font) {
      if (err) {
          alert('Could not load font: ' + err);
      } else {
          console.log("loaded the font",font);

          var Canvas = require('canvas')
            , Image = Canvas.Image
            , canvas = new Canvas(200, 200)
            , ctx = canvas.getContext('2d');
          var path = font.getPath('🐐🦃', 0, 150, 72);
          path.draw(ctx);
          console.log('<img src="' + canvas.toDataURL() + '" />');
      }
  });

The result looks like this:

The result looks like this:

I've tried fontkit, which is supposed to be able to read .ttc files, but it throws an error if I try to use the Apple Color Emoji font.

  var fontkit = require('fontkit');
  var font = fontkit.openSync('./build_scripts/Apple Color Emoji.ttc'); 
  // TypeError: font.layout is not a function

If I try the same with my converted .ttf file I end up with some incorrect svg:

  var fontkit = require('fontkit');
  var font = fontkit.openSync('./build_scripts/apple_color_emoji.ttf');
  var run = font.layout('🐐🦃');
  var svg = run.glyphs[0].path.toSVG();

  console.log(svg);
  // M-1 0ZM799 800Z

My question is, am I even approaching this the right way? Converting emoji that I already have on my machine to a .png or another format seems like something that should be fairly straightforward but I just can't get it to work.

EDIT:

I've found a list of emoji names by their hex codes in this repo (big shoutouts to rodrigopolo). Now I can simply use this:

var emoji = "😊".codePointAt(0).toString(16); //1f60a
var emojiFile = fs.readFileSync('./my-emoji-folder/' + emoji + '.png');

Still, would be great to know if somebody has a coding solution to this problem!

FURTHER EDIT:

Turns out the first solution I've found only included emoji up to Unicode 8.0, not Unicode 9.0. I've found a ruby gem gemoji that does emoji extraction. If you're not a ruby developer (I'm not), you can simply use the following commands in your shell:

git clone https://github.com/github/gemoji.git
cd gemoji
bundle install
bundle exec gemoji extract some-directory/emoji

You now have Unicode 9.0 emoji in your some-directory/emoji folder!

like image 434
user2634633 Avatar asked Apr 26 '17 12:04

user2634633


1 Answers

I was able to get this to work with fontkit by selecting a font from the font collection. I haven't found a case yet where using either of the TTFs included in the "Apple Color Emoji.ttc" gives different results.

const fs = require('fs');
const fontkit = require('fontkit');
const emoji = require('node-emoji');
const font = fontkit.openSync('./Apple Color Emoji.ttc').fonts[0];

let emo = emoji.get('100');
let run = font.layout(emo);
let glyph = run.glyphs[0].getImageForSize(128)

fs.writeFileSync('100.png', glyph.data);
like image 122
thebenmiller Avatar answered Oct 02 '22 16:10

thebenmiller