feat: 添加 pilmoji 依赖并支持渲染 emoji 表情

- 在 requirements.txt 中添加 pilmoji==2.0.5 依赖
- 重构 ImageRenderer 类,使用 Pilmoji 替代 PIL 的原生 text 方法以支持渲染 emoji 表情
- 将字体路径配置提取为类常量 DEFAULT_FONT_PATHS,并包含 Windows 和 Linux 的默认路径
- 初始化方法中的 font_paths 参数默认为 None,自动使用默认字体路径列表
This commit is contained in:
2026-04-04 22:27:00 +08:00
parent 45fbb947da
commit 2214e22b80
2 changed files with 19 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
"""图片生成模块 - 将文本渲染为图片"""
from PIL import Image, ImageDraw, ImageFont
from pilmoji import Pilmoji
import io
import base64
from typing import Tuple
@@ -8,6 +9,14 @@ from typing import Tuple
class ImageRenderer:
"""图片渲染器"""
DEFAULT_FONT_PATHS = [
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/truetype/noto/NotoColorEmoji.ttf",
"C:/Windows/Fonts/msyh.ttc",
"C:/Windows/Fonts/simhei.ttf",
"C:/Windows/Fonts/seguiemj.ttf",
]
def __init__(
self,
width: int = 800,
@@ -16,10 +25,7 @@ class ImageRenderer:
line_spacing: float = 1.4,
bg_color: Tuple[int, int, int] = (252, 252, 252),
text_color: Tuple[int, int, int] = (0, 0, 0),
font_paths: list = [
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", # 中文
"/usr/share/fonts/truetype/noto/NotoColorEmoji.ttf" # emoji
]
font_paths: list = None
):
"""
初始化图片渲染器
@@ -39,7 +45,7 @@ class ImageRenderer:
self.line_spacing = line_spacing
self.bg_color = bg_color
self.text_color = text_color
self.font_paths = font_paths or []
self.font_paths = font_paths or self.DEFAULT_FONT_PATHS.copy()
# 加载字体
self.font = self._load_font()
@@ -167,10 +173,10 @@ class ImageRenderer:
image = Image.new('RGB', (self.width, height), color=self.bg_color)
draw = ImageDraw.Draw(image)
# 绘制标题(加粗效果通过增大字体实现)
title_x = self.padding
title_y = self.padding
draw.text((title_x, title_y), title, font=title_font, fill=self.text_color)
with Pilmoji(image) as pilmoji:
pilmoji.text((title_x, title_y), title, font=title_font, fill=self.text_color)
# 绘制分割线
divider_y = title_y + title_height + 10
@@ -180,11 +186,11 @@ class ImageRenderer:
width=divider_height
)
# 绘制文本内容
y = divider_y + divider_spacing + self.padding
with Pilmoji(image) as pilmoji:
for line in all_lines:
if line: # 跳过空行
draw.text((self.padding, y), line, font=self.font, fill=self.text_color)
if line:
pilmoji.text((self.padding, y), line, font=self.font, fill=self.text_color)
y += total_line_height
# 转换为字节流

View File

@@ -49,6 +49,7 @@ nonebot_plugin_learning_chat==0.4.0
nonebot_plugin_withdraw==0.4.1
packaging==24.2
pillow==11.0.0
pilmoji==2.0.5
pipx==1.7.1
platformdirs==4.3.6
playwright==1.49.1