Search code examples
pythonpython-imaging-libraryemoji

Generating an image of multi character emoji using Pillow in python


I'm using Pillow to generate PNGs of emoji, using Google's Noto Emoji font (which can be downloaded from that page). It works well for basic emojis but multi character emojis are output as, well, multiple characters. I can't work out if it's possible to output them as single emoji.

This code:

from PIL import Image, ImageDraw, ImageFont

emoji = "๐Ÿ™‚"
image = Image.new("RGB", (600, 100), "#eeeeee")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("NotoEmoji-Bold.ttf", size=80)
draw.text((0, 0), emoji, font=font, fill="#000000")
image.save("emoji.png")

Outputs:

A light grey background with a single black smiley face emoji

Which is great.

But if I use a multi-character emoji, like a family:

emoji = "๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ"

then I get:

A light grey background with four smiling characters on, two adults, a girl with pigtails and a boy with a backwards baseball cap

Which is super cute, but I want the single-character family emoji:

A light grey background with a single emoji showing four stick figures holding hands, two adults and two children


Solution

  • I had to install the raqm library to get the multi-character emoji rendering correctly.

    On Ubuntu that meant doing apt-get install libraqm-dev.

    I thought I'd also have to specify it as the layout_engine for the font, i.e.:

    font = ImageFont.truetype("NotoEmoji-Bold.ttf", size=80, layout_engine=ImageFont.LAYOUT_RAQM)
    

    But it worked even without doing that, once raqm was installed. But I left it specified anyway, to be explicit.

    UPDATE: From Pillow v10 the layout_engine value needs to change:

    font = ImageFont.truetype("NotoEmoji-Bold.ttf", size=80, layout_engine=ImageFont.Layout.RAQM)