PIL如何相对于图像大小缩放文本大小

问题描述 投票:32回答:3

我正在尝试动态缩放文本,以将其放置在尺寸不同但已知尺寸的图像上。文本将用作水印。有什么方法可以根据图像尺寸缩放文本?我并不需要文字占据整个表面区域,只是要足够清晰可见,以便易于识别和删除。我正在使用Python Imaging Library版本1.1.7。在Linux上。

我希望能够设置文本大小与图像大小的比率,比如说大小的1/10。

我一直在寻找字体大小属性来更改大小,但是我没有运气来创建缩放它的算法。我想知道是否有更好的方法。

关于如何实现此目标的任何想法?

谢谢

python fonts image-manipulation python-imaging-library scaling
3个回答
66
投票

您可以增加字体大小,直到找到合适的大小为止。 font.getsize()是告诉您渲染文本有多大的功能。

import ImageFont, ImageDraw, Image

image = Image.open('hsvwheel.png')
draw = ImageDraw.Draw(image)
txt = "Hello World"
fontsize = 1  # starting font size

# portion of image width you want text width to be
img_fraction = 0.50

font = ImageFont.truetype("arial.ttf", fontsize)
while font.getsize(txt)[0] < img_fraction*image.size[0]:
    # iterate until the text size is just larger than the criteria
    fontsize += 1
    font = ImageFont.truetype("arial.ttf", fontsize)

# optionally de-increment to be sure it is less than criteria
fontsize -= 1
font = ImageFont.truetype("arial.ttf", fontsize)

print 'final font size',fontsize
draw.text((10, 25), txt, font=font) # put the text on the image
image.save('hsvwheel_txt.png') # save it

如果这对您来说不够有效,您可以实施寻根方案,但是我猜想font.getsize()函数与其余图像编辑过程相比是小的土豆。


8
投票

通常,当您更改字体大小时,它不会是字体大小的线性变化。

“非线性缩放”

现在这通常取决于软件,字体等。本示例摘自Typophile,并使用LaTex + Computer Modern字体。如您所见,它并不完全是线性缩放。因此,如果您在使用非线性字体缩放时遇到麻烦,那么我不确定如何解决它,但是可能有一个建议。

  1. 将字体渲染为所需大小,然后通过常规图像缩放算法将其放大/缩小...
  2. 仅接受它不是完全线性缩放,并尝试创建某种表/算法,将为字体选择最接近的磅值以与图像大小匹配。

0
投票

我知道这是一个古老的问题,已经用我也使用过的solution回答了。谢谢@Paul!

尽管每次迭代将字体大小增加一倍可能很耗时(至少对于我在可怜的小型服务器上来说是如此)。因此,例如。小文字(如“ Foo”)大约需要1-2秒,具体取决于图像大小。

为解决此问题,我调整了Pauls代码,以便它搜索数字的方式类似于二进制搜索。

breakpoint = img_fraction * photo.size[0]↵
jumpsize = 75↵
while True:↵
    if font.getsize(text)[0] < breakpoint:↵
        fontsize += jumpsize↵
    else:↵
        jumpsize = int(jumpsize / 2)↵
        fontsize -= jumpsize↵
    font = ImageFont.truetype(font_path, fontsize)↵
    if jumpsize <= 1:↵
        break↵

像这样,它将增加字体大小,直到它超过断点为止,然后从那里开始上下移动(将跳转大小每次减小一半),直到其大小合适为止。

这样,我可以将步长从200+减少到大约10,因此从1-2秒减少到0.04至0.08秒。

这是Pauls代码的直接替代(对于while语句及其后两行,因为您已经在while中获得了字体正确的字体大小]

这是在几分钟内完成的,因此,任何改进都值得赞赏!我希望这可以为正在寻求更高性能的解决方案的人提供帮助。

© www.soinside.com 2019 - 2024. All rights reserved.