如何使用 PIL.ImageDraw.Draw.text 设置锚点以适合图像中心的文本?

How to set anchor to fit the text at center of image with PIL.ImageDraw.Draw.text?

使用 Pillow 库在图像上绘制文本,尝试通过选项 anchor='mm' 使文本适合锚定在图像中心,但它看起来不完全是图像中心。

演示代码

from PIL import Image, ImageDraw, ImageFont

im = Image.new("RGBA", (500, 500), (255, 255, 255, 255))
font = ImageFont.truetype(font='arial.ttf', size=320)
draw = ImageDraw.Draw(im)
draw.text((250, 250), "123", font=font, fill='black', anchor='mm')
im.show()

结果:

期望值:

文本看起来未对齐的原因是 1 左侧有一点边距,pillow 会对齐包含此边距的文本。

在两端添加0将可视化它正确居中并且在1处有较大的边距。

如果要对齐不包括边距的文本,ImageFont.getmask 很有帮助。

def get_offset_for_true_mm(text, draw, font):
    anchor_bbox = draw.textbbox((0, 0), text, font=font, anchor='lt')
    anchor_center = (anchor_bbox[0] + anchor_bbox[2]) // 2, (anchor_bbox[1] + anchor_bbox[3]) // 2
    mask_bbox = font.getmask(text).getbbox()
    mask_center = (mask_bbox[0] + mask_bbox[2]) // 2, (mask_bbox[1] + mask_bbox[3]) // 2
    return anchor_center[0] - mask_center[0], anchor_center[1] - mask_center[1]


im = Image.new("RGBA", (500, 500), (255, 255, 255, 255))
font = ImageFont.truetype(font='arial.ttf', size=320)
draw = ImageDraw.Draw(im)
text = "123"
offset = get_offset_for_true_mm(text, draw, font)
draw.text((250 + offset[0], 250 + offset[1]), text, font=font, fill='black', anchor='mm')
im.show()

结果: