如何在 PIL 中对文本进行紧排
How to kern text in PIL
我正在处理一个需要逐像素精确度的问题,因此我需要能够以比 PIL 提供的方式更多的方式来处理文本。特别是关于字距调整。有一个功能允许您禁用字距调整,但不能控制数量。
由于 PIL 中与准确测量文本大小相关的错误,此问题变得更具挑战性。关于这个问题有很多 post,但最有用的信息是这里的 SO post,How to get the font pixel height using PIL's ImageFont class? and a blog article, How to properly calculate text size in PIL images
我的代码仅供我自己使用,但如果有人遇到类似问题,我相信它可以很容易地根据您自己的需要进行调整。
我的主要职能是:
def get_text_width(text_string, font):
return font.getmask(text_string).getbbox()[2]
def kern(name, draw_object, y, space, font, fill):
chars = [char for char in name]
total_width = 0
for char in chars:
width_text = get_text_width(char, font)
total_width += (width_text + int(space))
__, height_text = draw_object.textsize(name, font)
__, offset_y = font.getoffset(name)
height_text += offset_y
width_adjuster = 0
for char in chars:
width_text = get_text_width(char, font)
top_left_x = (473 / 2 - total_width / 2) + width_adjuster
top_left_y = (40 / 2 - height_text / 2) + y
xy = top_left_x, top_left_y
width_adjuster += width_text + int(space)
print(f"char:{char},width_text:{width_text},xy:{xy},width_adjuster:{width_adjuster}")
draw_object.text(xy, char, font=font, fill=fill)
它在下面给出了一个很好的输出。然而,它并不完全精确。字母之间的像素数会随着字体的不同而略有不同。我还没有找到标准化的方法,所以当我在我的 GUI 中输入字距调整值时,我接受了这个事实,它只是一个相对于字体的标量,而不是像素数
我正在处理一个需要逐像素精确度的问题,因此我需要能够以比 PIL 提供的方式更多的方式来处理文本。特别是关于字距调整。有一个功能允许您禁用字距调整,但不能控制数量。
由于 PIL 中与准确测量文本大小相关的错误,此问题变得更具挑战性。关于这个问题有很多 post,但最有用的信息是这里的 SO post,How to get the font pixel height using PIL's ImageFont class? and a blog article, How to properly calculate text size in PIL images
我的代码仅供我自己使用,但如果有人遇到类似问题,我相信它可以很容易地根据您自己的需要进行调整。
我的主要职能是:
def get_text_width(text_string, font):
return font.getmask(text_string).getbbox()[2]
def kern(name, draw_object, y, space, font, fill):
chars = [char for char in name]
total_width = 0
for char in chars:
width_text = get_text_width(char, font)
total_width += (width_text + int(space))
__, height_text = draw_object.textsize(name, font)
__, offset_y = font.getoffset(name)
height_text += offset_y
width_adjuster = 0
for char in chars:
width_text = get_text_width(char, font)
top_left_x = (473 / 2 - total_width / 2) + width_adjuster
top_left_y = (40 / 2 - height_text / 2) + y
xy = top_left_x, top_left_y
width_adjuster += width_text + int(space)
print(f"char:{char},width_text:{width_text},xy:{xy},width_adjuster:{width_adjuster}")
draw_object.text(xy, char, font=font, fill=fill)
它在下面给出了一个很好的输出。然而,它并不完全精确。字母之间的像素数会随着字体的不同而略有不同。我还没有找到标准化的方法,所以当我在我的 GUI 中输入字距调整值时,我接受了这个事实,它只是一个相对于字体的标量,而不是像素数