尽管其他答案说字体大小不是线性缩放的,但在我测试的所有示例中,它们都是线性缩放的(在1-2%之内)。
因此,如果您需要一个更简单、更有效的版本,它可以在几个百分点内工作,您可以复制/粘贴以下内容:
from PIL import ImageFont, ImageDraw, Image
def find_font_size(text, font, image, target_width_ratio):
tested_font_size = 100
tested_font = ImageFont.truetype(font, tested_font_size)
observed_width, observed_height = get_text_size(text, image, tested_font)
estimated_font_size = tested_font_size / (observed_width / image.width) * target_width_ratio
return round(estimated_font_size)
def get_text_size(text, image, font):
im = Image.new('RGB', (image.width, image.height))
draw = ImageDraw.Draw(im)
return draw.textsize(text, font)
函数
find_font_size()
可以像这样使用(完整的示例):
width_ratio = 0.5 # Portion of the image the text width should be (between 0 and 1)
font_family = "arial.ttf"
text = "Hello World"
image = Image.open('image.jpg')
editable_image = ImageDraw.Draw(image)
font_size = find_font_size(text, font_family, image, width_ratio)
font = ImageFont.truetype(font_family, font_size)
print(f"Font size found = {font_size} - Target ratio = {width_ratio} - Measured ratio = {get_text_size(text, image, font)[0] / image.width}")
editable_image.text((10, 10), text, font=font)
image.save('output.png')
对于一张225x225的图片,将会打印:
>> Font size found = 22 - Target ratio = 0.5 - Measured ratio = 0.502
我测试了各种字体和图片大小的
find_font_size()
,在所有情况下都能正常工作。
如果你想知道这个函数是如何工作的,基本上是使用
tested_font_size
来确定如果我们使用特定的字体大小生成文本将得到哪个比例。然后,我们使用交叉乘法规则来获取目标字体大小。
我测试了不同的
tested_font_size
值,并发现只要它不太小,就不会有任何区别。