CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pilmoji

Emoji renderer for Pillow with Discord emoji support and multiple emoji sources

Pending
Overview
Eval results
Files

core-rendering.mddocs/

Main Rendering Interface

The Pilmoji class provides the core emoji rendering functionality for Pillow images. It manages emoji placement, text layout, resource lifecycle, and offers comprehensive control over rendering parameters through a context manager interface.

Capabilities

Pilmoji Class

Main emoji rendering interface that handles text rendering with emoji substitution, supporting both Unicode emojis and Discord custom emojis with configurable positioning, scaling, and source providers.

class Pilmoji:
    """
    The main emoji rendering interface.
    
    Parameters:
    - image: PIL.Image.Image - The Pillow image to render on
    - source: Union[BaseSource, Type[BaseSource]] - Emoji source (defaults to Twemoji)
    - cache: bool - Whether to cache emojis (default: True)
    - draw: Optional[ImageDraw.ImageDraw] - Drawing instance (auto-created if None)
    - render_discord_emoji: bool - Enable Discord emoji rendering (default: True)
    - emoji_scale_factor: float - Default emoji scaling factor (default: 1.0)
    - emoji_position_offset: Tuple[int, int] - Default emoji position offset (default: (0, 0))
    """
    
    def __init__(
        self,
        image: Image.Image,
        *,
        source: Union[BaseSource, Type[BaseSource]] = Twemoji,
        cache: bool = True,
        draw: Optional[ImageDraw.ImageDraw] = None,
        render_discord_emoji: bool = True,
        emoji_scale_factor: float = 1.0,
        emoji_position_offset: Tuple[int, int] = (0, 0)
    ) -> None: ...

Usage Example

from pilmoji import Pilmoji
from pilmoji.source import MicrosoftEmojiSource
from PIL import Image, ImageFont

# Create image and font
image = Image.new('RGB', (400, 100), (255, 255, 255))
font = ImageFont.load_default()

# Use Microsoft emoji source with custom scaling
with Pilmoji(
    image, 
    source=MicrosoftEmojiSource,
    emoji_scale_factor=1.2,
    emoji_position_offset=(0, -2)
) as pilmoji:
    pilmoji.text((10, 10), "Hello! 😊 How are you? 🌟", (0, 0, 0), font)

Text Rendering

Renders text with emoji support, handling multi-line text, custom positioning, and extensive formatting options compatible with Pillow's ImageDraw.text interface.

def text(
    self,
    xy: Tuple[int, int],
    text: str,
    fill: ColorT = None,
    font: FontT = None,
    anchor: str = None,
    spacing: int = 4,
    node_spacing: int = 0,
    align: str = "left",
    direction: str = None,
    features: str = None,
    language: str = None,
    stroke_width: int = 0,
    stroke_fill: ColorT = None,
    embedded_color: bool = False,
    *args,
    emoji_scale_factor: float = None,
    emoji_position_offset: Tuple[int, int] = None,
    **kwargs
) -> None:
    """
    Draws text with emoji rendering support, including multi-line text.
    
    Parameters:
    - xy: Tuple[int, int] - Position to render text
    - text: str - Text to render (supports Unicode and Discord emojis)
    - fill: ColorT - Text color
    - font: FontT - Font to use
    - spacing: int - Line spacing in pixels (default: 4)
    - node_spacing: int - Spacing between text/emoji nodes (default: 0)
    - emoji_scale_factor: float - Emoji scaling override
    - emoji_position_offset: Tuple[int, int] - Emoji position offset override
    - Additional parameters inherited from Pillow's ImageDraw.text
    """

Usage Example

# Multi-line text with custom emoji positioning
multiline_text = """
Welcome to our app! 👋
Features include:
• Fast processing ⚡
• Beautiful UI 🎨
• Discord support <:custom:123456789>
"""

with Pilmoji(image) as pilmoji:
    pilmoji.text(
        (20, 20), 
        multiline_text.strip(),
        fill=(50, 50, 50),
        font=font,
        spacing=6,
        node_spacing=2,
        emoji_scale_factor=1.1,
        emoji_position_offset=(1, -1)
    )

Text Size Calculation

Calculates text dimensions including emoji substitutions, supporting multi-line text and custom emoji scaling for accurate layout planning.

def getsize(
    self,
    text: str,
    font: FontT = None,
    *,
    spacing: int = 4,
    emoji_scale_factor: float = None
) -> Tuple[int, int]:
    """
    Calculate width and height of text when rendered with emojis.
    
    Parameters:
    - text: str - Text to measure
    - font: FontT - Font to use for measurement
    - spacing: int - Line spacing (default: 4)
    - emoji_scale_factor: float - Emoji scaling factor
    
    Returns:
    - Tuple[int, int] - (width, height) of rendered text
    """

Usage Example

text = "Hello! 👋 This is a test 🧪"

with Pilmoji(image) as pilmoji:
    width, height = pilmoji.getsize(text, font, emoji_scale_factor=1.2)
    print(f"Text dimensions: {width}x{height}")
    
    # Use dimensions for centering
    image_width, image_height = image.size
    x = (image_width - width) // 2
    y = (image_height - height) // 2
    
    pilmoji.text((x, y), text, (0, 0, 0), font)

Context Manager Support

Automatic resource management through context manager protocol, ensuring proper cleanup of HTTP sessions, cached emoji streams, and drawing resources.

def __enter__(self) -> Pilmoji: ...

def __exit__(self, *_) -> None: ...

def open(self) -> None:
    """
    Re-opens closed renderer.
    
    Raises:
    - ValueError: If renderer is already open
    """

def close(self) -> None:
    """
    Safely closes renderer and cleans up resources.
    
    Raises:
    - ValueError: If renderer is already closed
    """

Usage Example

# Automatic resource management
with Pilmoji(image) as pilmoji:
    pilmoji.text((10, 10), "Emoji text 🎉", (0, 0, 0), font)
# Resources automatically cleaned up

# Manual resource management
pilmoji = Pilmoji(image)
try:
    pilmoji.text((10, 10), "Emoji text 🎉", (0, 0, 0), font)
finally:
    pilmoji.close()

Install with Tessl CLI

npx tessl i tessl/pypi-pilmoji

docs

core-rendering.md

emoji-sources.md

index.md

text-processing.md

tile.json