Pillow,如何将文本置于图像中心

9

我使用 Pillow (PIL) 6.0 在图像中添加文本。我想把文本放在图像的中心。以下是我的代码:

import os
import string
from PIL import Image
from PIL import ImageFont, ImageDraw, ImageOps

width, height = 100, 100

text = 'H'
font_size = 100

os.makedirs('./{}'.format(text), exist_ok=True)

img = Image.new("L", (width, height), color=0)   # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
w, h = draw.textsize(text, font=font)
draw.text(((width-w)/2, (height-h)/2), text=text, fill='white', font=font)

img.save('H.png')

这里是输出结果:

输入图片描述,显示不出来请参考链接中的图片。

问题:

文字水平居中,但垂直方向没有居中。如何使其水平和垂直方向都居中?


你是否将 h 与你的“H”测量高度进行比较?这可能看起来像是一个行高问题... - thebjorn
这个回答解决了你的问题吗?如何使用PIL居中对齐文本? - bfontaine
2个回答

17

文本周围始终有一些额外的空间,例如如果我们创建一个大小与“H”相同的框

img = Image.new("L", (width, height), color=0)   # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
w, h = draw.textsize(text, font=font)
# draw.text(((width-w)/2, (height-h)/2), text=text, fill='white', font=font)
# img.save('H.png')
img2 = Image.new("L", (w, h), color=0)   # "L": (8-bit pixels, black and white)
draw2 = ImageDraw.Draw(img2)
draw2.text((0, 0)), text=text, fill='white', font=font)
img2.save('H.png')

给出边界框:

输入图像描述

知道行高通常比字形/字符大约20%(+一些试错),我们可以算出额外空间的范围。(宽度的额外空间是平均分配的,因此对于居中并不重要)。

draw2.text((0, 0 - int(h*0.21)), text=text, fill='white', font=font)
将“H”移到顶部的代码如下所示:

enter image description here

将此代码插入您的原始代码中:
img = Image.new("L", (width, height), color=0)   # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
w, h = draw.textsize(text, font=font)
h += int(h*0.21)
draw.text(((width-w)/2, (height-h)/2), text=text, fill='white', font=font)
img.save('H.png')

给出:

输入图像描述

0.21因子通常适用于同一字体的大范围字号。例如,只需插入字号30:

输入图像描述


它能处理非英文字母吗? - Akhil Nadh PC
1
这个过程当然会记住试错的部分,例如对于一个 Åh += int(h*0.21) 需要改为 h += int(n*0.1),因为圆圈使字母比 H 更高(我有点惊讶你还没有自己尝试过,所有的代码都在那里...) - thebjorn

1
使用锚点可以帮助解决这个问题。
import os
import string
from PIL import Image
from PIL import ImageFont, ImageDraw, ImageOps

width, height = 100, 100

text = 'H'
font_size = 100

os.makedirs('./{}'.format(text), exist_ok=True)

img = Image.new("L", (width, height), color=0)   # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
draw.text(((width)/2, (height)/2), text=text, fill='white', font=font, anchor="mm", align='center')

img.save('H.png')

没有 wh 也可以正常工作
附注:我已经测试过,它也可以很好地处理非英文字符


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接