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:
@@ -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,12 +186,12 @@ class ImageRenderer:
|
||||
width=divider_height
|
||||
)
|
||||
|
||||
# 绘制文本内容
|
||||
y = divider_y + divider_spacing + self.padding
|
||||
for line in all_lines:
|
||||
if line: # 跳过空行
|
||||
draw.text((self.padding, y), line, font=self.font, fill=self.text_color)
|
||||
y += total_line_height
|
||||
with Pilmoji(image) as pilmoji:
|
||||
for line in all_lines:
|
||||
if line:
|
||||
pilmoji.text((self.padding, y), line, font=self.font, fill=self.text_color)
|
||||
y += total_line_height
|
||||
|
||||
# 转换为字节流
|
||||
img_byte_arr = io.BytesIO()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user