Pilmoji is an emoji renderer for Pillow, Python's imaging library.
Pilmoji comes equipped with support for both unicode emojis and Discord emojis.
- Discord emoji support
- Multi-line rendering support
- Emoji position and/or size adjusting
- Many built-in emoji sources
- Optional caching
You must have Python 3.8 or higher in order to install Pilmoji.
Installation can be done with pip:
$ pip install -U pilmojiOptionally, you can add the [requests] option to install requests
alongside Pilmoji:
$ pip install -U pilmoji[requests]The option is not required, instead if requests is not installed,
Pilmoji will fallback to use the builtin urllib.
You may also install from Github.
from pilmoji import Pilmoji
from PIL import Image, ImageFont
my_string = '''
Hello, world! 👋 Here are some emojis: 🎨 🌊 😎
I also support Discord emoji: <:rooThink:596576798351949847>
'''
with Image.new('RGB', (550, 80), (255, 255, 255)) as image:
font = ImageFont.truetype('arial.ttf', 24)
with Pilmoji(image) as pilmoji:
pilmoji.text((10, 10), my_string.strip(), (0, 0, 0), font)
image.show()As seen from the example, Pilmoji defaults to the Twemoji emoji source.
If you prefer emojis from a different source, for example Microsoft, simply
set the source kwarg in the constructor to a source found in the
pilmoji.source module:
from pilmoji.source import MicrosoftEmojiSource
with Pilmoji(image, source=MicrosoftEmojiSource) as pilmoji:
...It is also possible to create your own emoji sources via subclass.
Pilmoji provides a special emoji source called LocalCachedEmojiSource that caches emojis locally on your file system. This source automatically:
- Downloads emojis from a base source
- Resizes them to a consistent size (40x40 pixels)
- Saves them to your local disk for future use
This is particularly useful for applications that need to:
- Speed up repeated emoji rendering
- Reduce network requests
- Maintain consistent emoji sizes
- Share emoji cache across multiple runs
from pilmoji import Pilmoji
from pilmoji.source import LocalCachedEmojiSource
from PIL import Image, ImageFont
with Image.new('RGB', (550, 80), (255, 255, 255)) as image:
font = ImageFont.truetype('arial.ttf', 24)
# Create a cached source (defaults to Twemoji as base source)
cached_source = LocalCachedEmojiSource()
with Pilmoji(image, source=cached_source) as pilmoji:
pilmoji.text((10, 10), "Hello, world! 👋 🎨 🌊 😎", (0, 0, 0), font)
image.show()You can specify a different base emoji source and cache directory:
from pilmoji.source import LocalCachedEmojiSource, AppleEmojiSource
# Use Apple-style emojis with a custom cache directory
cached_source = LocalCachedEmojiSource(
base_source=AppleEmojiSource(), # Use Apple emojis instead of Twemoji
cache_dir="./my_emoji_cache" # Store cached emojis in a custom directory
)The first time you render an emoji with LocalCachedEmojiSource, it will download and process the image. On subsequent runs, it will directly load from the local cache, resulting in significantly faster rendering times, especially for applications that use the same emojis repeatedly.
If an emoji looks too small or too big, or out of place, you can make fine adjustments
with the emoji_scale_factor and emoji_position_offset kwargs:
pilmoji.text((10, 10), my_string.strip(), (0, 0, 0), font,
emoji_scale_factor=1.15, emoji_position_offset=(0, -2))Contributions are welcome. Make sure to follow PEP-8 styling guidelines.