【问题标题】:PIL (Pillow) getsize_multiline() in while loop going into infinite loop?PIL(Pillow)getsize_multiline()在while循环中进入无限循环?
【发布时间】:2020-02-10 14:45:21
【问题描述】:

为什么这几行代码会陷入死循环?这似乎是我的代码唯一可能有问题的部分,因为将其注释掉后,其他一切都可以正常工作。

#Increase the font size till the text is just a little too wide
while selected_font.getsize_multiline(beautiful_text)[0] < (0.8 * img.size[0]):
    selected_font.size += 2

#If the text is too long, reduce the font size a little...
while selected_font.getsize_multiline(beautiful_text)[1] > (0.7 * img.size[1]):
    selected_font.size -= 2
    #..and then increase the number of characters per line till it's wide enough...
    while selected_font.getsize_multiline(beautiful_text)[0] < (0.8 * img.size[0]):
        wrapper.width += 2
        beautiful_text = wrapper.fill(input_text)
    #...rewrap the text, test again, and keep repeating till it sits well

我知道selected_font.getsize_multiline(beautiful_text) 是一个有效的调用,它返回一个元组,img.size 也是如此。增加字体大小后,文本框的宽度肯定会增加,那为什么会导致无限循环呢?

【问题讨论】:

  • 我建议您按照本文中概述的步骤操作:ericlippert.com/2014/03/05/how-to-debug-small-programs。如果这没有为您找到问题,它至少可以让您提出一个更有针对性的问题。
  • @TurePålsson 感谢您的建议,我已相应地编辑了我的帖子
  • 您仍然有 3 个“while”循环,每个循环都可能运行异常。你检查过它是哪一个吗?您是否查看了 getsize_multiline 的返回值并检查它们的行为是否符合您的预期?
  • @TurePålsson 据我所知,其中两个是无限的。我从相当小的字体开始,所以如果我绕过第一个循环,文本甚至不够大,无法进入第二个循环。当我硬编码它以从一个巨大的字体开始时,它会卡在第二个循环中,但只有当文本很长时,我才会相信它是第一个外部循环和内部 while 循环,它们可能是无限的。
  • 那么 getsize_multiline 的返回值呢?他们的行为是否符合您的预期?

标签: python python-imaging-library


【解决方案1】:

我修复了这个错误。问题在于ImageFont.truetype('fontfile', size = desired_size)返回的字体对象 (在这种情况下,对象 selected_font)具有不可变的 size 属性。

selected_font = ImageFont.truetype('Arial.ttf', size = 20)
print(selected_font.size)       #output: 20
selected_font.size = 10         #doesn't raise an error
print(selected_font.size)       #output: 20

因此这一行不会更新我在循环中检查的变量

selected_font.size += 2         #does nothing, and raises no errors

更令人困惑的是,TextWrapper 模块的线宽确实具有可变大小属性 变量

wrapper.width += 5              #works as you'd expect

不管怎样,我用这段代码解决了我的问题

fontsize = 10

while selected_font.getsize_multiline(beautiful_text)[1] > (0.7 * img.size[1]):
    fontsize -= 2
    selected_font = ImageFont.truetype("src/CaviarDreams.ttf", size = fontsize)

其他循环也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 2015-06-25
    • 2014-11-13
    • 1970-01-01
    • 2014-03-29
    相关资源
    最近更新 更多