尽管其他答案说字体大小不是线性缩放的,但在我测试的所有示例中,它们确实是线性缩放的(在 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的不同值,发现只要不是太小,没有任何区别。