修复通知图片徽章文字垂直对齐
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user