修复通知图片徽章文字垂直对齐

This commit is contained in:
2026-09-22 22:22:03 +08:00
parent f4d3abcd09
commit 56e788ec38
2 changed files with 146 additions and 1 deletions

View File

@@ -172,6 +172,32 @@ class ImageRenderer:
bbox = draw.textbbox((0, 0), text, font=font)
return bbox[2] - bbox[0], bbox[3] - bbox[1]
def _vertical_text_origin(
self,
center_y: int,
text: str,
font: ImageFont.FreeTypeFont,
) -> int:
"""
计算让文本可见墨迹在指定高度内垂直居中所需的绘制原点 y。
PIL 以字体升部基准线定位,textbbox 相对绘制原点的 top 通常不为 0
(例如 19px 微软雅黑的中文 bbox 为 (0, 5, w, 24)),直接按
bbox 高度居中会让文字整体偏下,这里改用真实墨迹上下边界来对齐。
Args:
center_y: 目标垂直中心线(图像绝对坐标)
text: 文本内容
font: 字体对象
Returns:
绘制原点 y 坐标
"""
draw = self._get_measuring_draw()
bbox = draw.textbbox((0, 0), text, font=font)
# bbox top/bottom 是相对绘制原点的偏移,故墨迹中点 = origin_y + (bbox[1] + bbox[3]) / 2
return int(round(center_y - (bbox[1] + bbox[3]) / 2))
def _char_width(self, char: str, font: ImageFont.FreeTypeFont) -> float:
"""
测量单个字符宽度,缺字形时按方块宽度兜底。
@@ -419,7 +445,12 @@ class ImageRenderer:
)
brand_top = margin + max((header_height - brand_height) // 2, 0)
badge_text_top = badge_top + max((badge_height - badge_text_height) // 2, 0)
# 按真实墨迹边界居中,避免 textbbox top 偏移导致徽章文字偏下
badge_text_top = self._vertical_text_origin(
badge_top + badge_height // 2,
badge_text,
badge_font,
)
with ExitStack() as stack:
pilmoji: Optional[Pilmoji] = None