Skip to content

Commit

Permalink
Merge pull request #882 from jacebrowning/emoji-support
Browse files Browse the repository at this point in the history
Add initial emoji support
  • Loading branch information
jacebrowning authored Nov 24, 2024
2 parents b80f96f + 80fa6e1 commit 2cdc8c7
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 68 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Revision History

## 11.1b1

- Added emoji support.

## 11.0

- Removed support for legacy `alt` query parameter for custom backgrounds.
Expand Down
2 changes: 2 additions & 0 deletions app/models/text.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
from dataclasses import dataclass

import emoji
from sanic.log import logger
from spongemock import spongemock

Expand Down Expand Up @@ -87,6 +88,7 @@ def normalize(self, text: str | None) -> str:
return text

def stylize(self, text: str, **kwargs) -> str:
text = emoji.emojize(text, language="alias")
lines = [line for line in kwargs.get("lines", [text]) if line.strip()]

if self.style == "none":
Expand Down
Empty file added app/tests/images/.flag
Empty file.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion app/tests/test_utils_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ async def test_custom_style_rotated(images):


def test_special_characters(images, template):
lines = ["Special? 100% #these-memes", "template_rating: 9/10"]
lines = ["Special? 👋 100% #these-memes", "template_rating: 9/10"]
utils.images.save(template, lines, directory=images)


Expand Down
1 change: 1 addition & 0 deletions app/types.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Literal, Union

from PIL.Image import Image as ImageType # noqa
from PIL.ImageDraw import ImageDraw as DrawType # noqa
from PIL.ImageFont import FreeTypeFont as FontType # noqa

Box = tuple[int, int, int, int]
Expand Down
57 changes: 36 additions & 21 deletions app/utils/images.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from __future__ import annotations

import io
from contextlib import contextmanager
from pathlib import Path
from typing import Iterator, cast

import emoji
import webp
from PIL import (
Image,
Expand All @@ -14,11 +16,12 @@
ImageSequence,
UnidentifiedImageError,
)
from pilmoji import Pilmoji
from sanic.log import logger

from .. import settings
from ..models import Font, Template, Text
from ..types import Align, Dimensions, FontType, ImageType, Offset, Point
from ..types import Align, Dimensions, DrawType, FontType, ImageType, Offset, Point

EXCEPTIONS = (
OSError,
Expand Down Expand Up @@ -253,16 +256,17 @@ def render_image(
draw.rectangle(xy, outline=outline)

rows = text.count("\n") + 1
draw.text(
(-offset[0], -offset[1]),
text,
text_fill,
font,
spacing=-offset[1] / (rows * 2),
align=align,
stroke_width=stroke_width,
stroke_fill=stroke_fill,
)
with emoji_support(box, draw, text) as draw:
draw.text(
(-offset[0], -offset[1]),
text,
text_fill,
font,
spacing=-offset[1] / (rows * 2),
align=align,
stroke_width=stroke_width,
stroke_fill=stroke_fill,
)

box = box.rotate(angle, resample=Image.Resampling.BICUBIC, expand=True)
image.paste(box, point, box)
Expand Down Expand Up @@ -386,16 +390,17 @@ def render_animation(
draw.rectangle(xy, outline=outline)

rows = text.count("\n") + 1
draw.text(
(-offset[0], -offset[1]),
text,
text_fill,
font,
spacing=-offset[1] / (rows * 2),
align=align,
stroke_width=stroke_width,
stroke_fill=stroke_fill,
)
with emoji_support(box, draw, text) as draw:
draw.text(
(-offset[0], -offset[1]),
text,
text_fill,
font,
spacing=-offset[1] / (rows * 2),
align=align,
stroke_width=stroke_width,
stroke_fill=stroke_fill,
)

try:
box = box.rotate(angle, resample=Image.Resampling.LANCZOS, expand=True)
Expand Down Expand Up @@ -554,6 +559,16 @@ def add_counter(
return Image.alpha_composite(image, box)


@contextmanager
def emoji_support(image: ImageType, draw: DrawType, text: str):
if emoji.emoji_count(text):
pilmoji = Pilmoji(image, render_discord_emoji=False, emoji_scale_factor=0.8)
yield pilmoji
pilmoji.close()
else:
yield draw


def get_image_elements(
template: Template,
lines: list[str],
Expand Down
82 changes: 38 additions & 44 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]

name = "memegen"
version = "11.0"
version = "11.1b1"
description = "The free and open source API to generate memes."
authors = ["Jace Browning <[email protected]>"]
license = "MIT"
Expand All @@ -10,7 +10,7 @@ packages = [{ include = "app" }]

[tool.poetry.dependencies]

python = "3.12.5"
python = "~3.12.2"

# Sanic
sanic = "~24.6" # run 'poetry update sanic-ext sanic-testing' when changing this
Expand All @@ -23,6 +23,7 @@ pygments = "^2.15.0"

# Images
pillow = "^10.4" # run 'poetry update types-pillow' when changing this
pilmoji = { git = "https://github.com/jay3332/pilmoji", branch = "2.0" }
spongemock = "~0.3.4"

# Utilities
Expand Down

0 comments on commit 2cdc8c7

Please sign in to comment.