如果字体(例如:Times New Roman)和大小(例如:12pt)已知,如何计算字符串的长度(例如:“Hello world”)的像素数,可能只是大概的?我需要这个来对在Windows应用程序中显示的文本进行手动右对齐,因此我需要调整空格的数量以获得对齐。
从 Pillow v9.2.0
开始,.getsize
已被弃用,并将在 2023-07-01 的 Pillow v10
中删除。请改用 getbbox
或 getlength
。
已在 python 3.11.2
和 pillow v9.4.0
中测试通过
from PIL import ImageFont
font = ImageFont.truetype('times.ttf', 12)
left, top, right, bottom = font.getbbox('Hello world')
width = font.getlength('Hello world')
print(f'left: {left}, top: {top}, right: {right}, bottom: {bottom}, width: {width}')
[out]:
left: 0, top: 2, right: 58, bottom: 11, width: 57.0
根据@Selcuk的评论,我找到了答案:
from PIL import ImageFont
font = ImageFont.truetype('times.ttf', 12)
size = font.getsize('Hello world')
print(size)
这是一个打印(x, y)尺寸的函数:
(58, 11)
以下是函数的代码:
from PIL import ImageFont
def get_pil_text_size(text, font_size, font_name):
font = ImageFont.truetype(font_name, font_size)
size = font.getsize(text)
return size
get_pil_text_size('Hello world', 12, 'times.ttf')
另一种方法是按如下方式向Windows询问:
import ctypes
def GetTextDimensions(text, points, font):
class SIZE(ctypes.Structure):
_fields_ = [("cx", ctypes.c_long), ("cy", ctypes.c_long)]
hdc = ctypes.windll.user32.GetDC(0)
hfont = ctypes.windll.gdi32.CreateFontA(points, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, font)
hfont_old = ctypes.windll.gdi32.SelectObject(hdc, hfont)
size = SIZE(0, 0)
ctypes.windll.gdi32.GetTextExtentPoint32A(hdc, text, len(text), ctypes.byref(size))
ctypes.windll.gdi32.SelectObject(hdc, hfont_old)
ctypes.windll.gdi32.DeleteObject(hfont)
return (size.cx, size.cy)
print(GetTextDimensions("Hello world", 12, "Times New Roman"))
print(GetTextDimensions("Hello world", 12, "Arial"))
这将显示:
(47, 12)
(45, 12)
()
才能使用print,但除此之外它可以工作。但是两种方法之间存在显着的x大小差异,这有点奇怪。 - EquipDevgetsize()
使用的是另一个维度。 - Martin Evansfrom PIL import ImageFont
multiline_string = 'Quick test of multiline text\r\nNew line\nAnother new line here'
font = ImageFont.truetype('arial.ttf', 8)
bboxes = [font.getbbox(k) for k in multiline_string.splitlines()]
width = max([(b[2]-b[0]) for b in bboxes])
height = sum([(b[3]) for b in bboxes])
print('width=' + str(width) + ', height=' + str(height))
from PIL import Image, ImageFont, ImageDraw
multiline_test = 'Quick test of multiline text\r\nNew line\nAnother new line here'
img = Image.new("RGB", (1000, 1000), (255, 255, 255)) # create an image filled with white color
curr_font = ImageFont.truetype("arial.ttf", 8) # get a font "Arial" with size = 8
curr_context = ImageDraw.Draw(img) # get drawing context of the image
result_box = curr_context.multiline_textbbox((0,0), multiline_test, font=curr_font, font_size=8) # get resulting boundry-box for multiline text with curr_font and font-size = 8
print(result_box) # print the result-box (the width and height could be retrieved there)
# Useful to see the result text:
# curr_context.multiline_text((0, 0), multiline_test, font=curr_font, fill=(0, 0, 0))
# img.show()