Skip to main content

Pilmoji for Parser

A simplified emoji renderer for Pillow, Python's imaging library. This is a streamlined fork optimized for use with nonebot-plugin-parser.

✨ Features

  • 🎨 Unicode Emoji Support - Render standard Unicode emojis
  • 💬 Discord Emoji Support - Render custom Discord emojis
  • 📝 Multi-line Text - Automatic line break handling
  • 🎭 Multiple Emoji Styles - Apple, Google, Twitter, Facebook
  • ⚡ Async/Await - Built with modern async Python
  • 💾 Smart Caching - Local file caching for better performance
  • 🔧 Simple API - Easy-to-use interface with sensible defaults

📦 Installation

Requirements: Python 3.10 or higher

pip install pilmoji-for-parser

Or install from source:

git clone https://github.com/fllesser/pilmoji-for-parser.git
cd pilmoji-for-parser
pip install .

🚀 Quick Start

Basic Usage (Unicode Emoji Only)

import asyncio
from pilmoji import Pilmoji
from PIL import Image, ImageFont

async def main():
    text = '''
    Hello, world! 👋 
    Here are some emojis: 🎨 🌊 😎
    Multi-line support! 🚀 ✨
    '''
    
    # Create image
    image = Image.new('RGB', (550, 150), (255, 255, 255))
    font = ImageFont.truetype('arial.ttf', 24)
    
    # Render text with emojis
    async with Pilmoji() as pilmoji:
        await pilmoji.text(image, (10, 10), text.strip(), font, fill=(0, 0, 0))
    
    image.save('output.png')
    image.show()

asyncio.run(main())

With Discord Emoji Support

async def main():
    text = '''
    Unicode emoji: 👋 🎨 😎
    Discord emoji: <:custom:123456789012345678>
    '''
    
    image = Image.new('RGB', (550, 100), (255, 255, 255))
    font = ImageFont.truetype('arial.ttf', 24)
    
    async with Pilmoji() as pilmoji:
        await pilmoji.text_with_discord_emoji(
            image, (10, 10), text.strip(), font, fill=(0, 0, 0)
        )
    
    image.save('output.png')

asyncio.run(main())

🎨 Emoji Styles

Choose from different emoji styles:

from pilmoji import Pilmoji, EmojiStyle, EmojiCDNSource

# Apple style (default)
source = EmojiCDNSource(style=EmojiStyle.APPLE)

# Google style
source = EmojiCDNSource(style=EmojiStyle.GOOGLE)

# Twitter style
source = EmojiCDNSource(style=EmojiStyle.TWITTER)

# Facebook style
source = EmojiCDNSource(style=EmojiStyle.FACEBOOK)

async with Pilmoji(source=source) as pilmoji:
    await pilmoji.text(image, (10, 10), "Hello 👋", font)

🔧 API Reference

Pilmoji

Main class for rendering text with emojis.

Constructor:

Pilmoji(
    source: BaseSource = EmojiCDNSource(),
    cache: bool = True
)

Parameters:

  • source: Emoji source to use (default: EmojiCDNSource())
  • cache: Enable emoji caching (default: True)

Methods:

async text(image, xy, text, font, fill=None)

Render text with Unicode emoji support.

  • image: PIL Image object to render onto
  • xy: Tuple of (x, y) coordinates for text position
  • text: Text string to render (supports multiple lines)
  • font: PIL Font object
  • fill: Text color (default: black)

async text_with_discord_emoji(image, xy, text, font, fill=None)

Render text with both Unicode and Discord emoji support.

Parameters are the same as text().

EmojiCDNSource

Default emoji source using emojicdn.elk.sh.

Constructor:

EmojiCDNSource(
    style: EmojiStyle = EmojiStyle.APPLE,
    cache_dir: Path | None = None
)

Parameters:

  • style: Emoji style to use (Apple, Google, Twitter, Facebook)
  • cache_dir: Custom cache directory (default: ~/.cache/pilmoji)

🔌 Custom Emoji Sources

Create your own emoji source by subclassing BaseSource:

from pilmoji import BaseSource
from io import BytesIO

class CustomEmojiSource(BaseSource):
    async def get_emoji(self, emoji: str) -> BytesIO | None:
        # Your custom emoji fetching logic
        pass
    
    async def get_discord_emoji(self, id: int) -> BytesIO | None:
        # Your custom Discord emoji fetching logic
        pass

# Use your custom source
async with Pilmoji(source=CustomEmojiSource()) as pilmoji:
    await pilmoji.text(image, (10, 10), "Hello 👋", font)

📝 Examples

Different Text Colors

# Red text
await pilmoji.text(image, (10, 10), "Red text 🔴", font, fill=(255, 0, 0))

# RGB tuple
await pilmoji.text(image, (10, 50), "Blue text 🔵", font, fill=(0, 0, 255))

# RGBA tuple with transparency
await pilmoji.text(image, (10, 90), "Semi-transparent 👻", font, fill=(0, 0, 0, 128))

Multi-line Text

text = """Line 1 with emoji 🎨
Line 2 with emoji 🌊
Line 3 with emoji 😎"""

await pilmoji.text(image, (10, 10), text, font, fill=(0, 0, 0))

Without Context Manager

pilmoji = Pilmoji()
await pilmoji.text(image, (10, 10), "Hello 👋", font)
await pilmoji.aclose()  # Don't forget to close!

🧪 Development

Setup

# Clone the repository
git clone https://github.com/fllesser/pilmoji-for-parser.git
cd pilmoji-for-parser

# Install dependencies
uv sync --dev

# Run tests
uv run pytest

# Run linting
uv run ruff check src/

Running Tests

# Run all tests
uv run poe test

# Run with coverage
uv run pytest --cov=src --cov-report=html

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

Metadata

Release files for pilmoji-for-parser 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pilmoji-for-parser 0.2.0
File Size Uploaded Provenance Actions
pilmoji_for_parser-0.2.0.tar.gz 8.9 kB With provenance Details for pilmoji_for_parser-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pilmoji-for-parser 0.2.0
File Interpreter ABI Platform Actions
pilmoji_for_parser-0.2.0-py3-none-any.whl Python 3 none any Details for pilmoji_for_parser-0.2.0-py3-none-any.whl

Total release size: 18.2 kB

Release files / pilmoji_for_parser-0.2.0.tar.gz

Download URL pilmoji_for_parser-0.2.0.tar.gz
Size 8.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ac2827c7f1e439a42c922639e17d9307a4b9bac26358d35a338f6e822510cfb3
BLAKE2b-256 checksum
How to use checksums
39ac14034c804d5c22f7576b786161b68d44f56dab5d248f49a1df65c53713fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 3, 2025.

Transparency log

Release files / pilmoji_for_parser-0.2.0-py3-none-any.whl

Download URL pilmoji_for_parser-0.2.0-py3-none-any.whl
Size 9.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f2ecd1b25644fcfb8e45d38c83565464c5d3e150387c02b4bdefa50c3d7b2687
BLAKE2b-256 checksum
How to use checksums
b19a7ada4d6d14abc62f0c081bf4336b1efb076afce2b7b5d88bc4d99841d785
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 3, 2025.

Transparency log

Security for pilmoji-for-parser 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pilmoji_for_parser-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 3, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page