如何使用 Pillow Python 获取带换行符的文本大小

问题描述 投票:0回答:2

我正在尝试使用 Pillow 将文本置于框中居中。我已按照这篇 stackoverflow post 中的说明进行操作,这给出了所需的结果。但是,如果我在单词之间添加换行符,文本将无法正确调整大小并且会偏离中心。

这里是没有换行符的代码示例:

title_text = "Hello World"

img = Image.new(size=(400, 300), mode='RGB')
draw = ImageDraw.Draw(img)
font_path = "/content/Charlie don't surf.ttf"

# draw white rectangle 200x100 with center in 200,150
draw.rectangle((200-100, 150-50, 200+100, 150+50), fill='white')
draw.line(((0, 150), (400, 150)), 'gray')
draw.line(((200, 0), (200, 300)), 'gray')

# find font size for text `"Hello World"` to fit in rectangle 200x100
selected_size = 1
for size in range(1, 150):
    title_font = ImageFont.FreeTypeFont(font_path, size=size)
    w, h = title_font.getsize(title_text)
    
    if w > 200 or h > 100:
        break
        
    selected_size = size
    
# draw text in center of rectangle 200x100        
title_font = ImageFont.FreeTypeFont(font_path, size=selected_size)

draw.text((200-(w//2), 150-h//2), title_text, fill='red', font=title_font)

display(img)

请注意,文本已居中并根据需要调整大小。

但是如果我将

title_text = "Hello World"
更改为
title_text = "Hello\nWorld"
以添加换行符。我明白了:

title_text = "Hello\nWorld"

img = Image.new(size=(400, 300), mode='RGB')
draw = ImageDraw.Draw(img)
font_path = "/content/Charlie don't surf.ttf"

# draw white rectangle 200x100 with center in 200,150
draw.rectangle((200-100, 150-50, 200+100, 150+50), fill='white')
draw.line(((0, 150), (400, 150)), 'gray')
draw.line(((200, 0), (200, 300)), 'gray')

# find font size for text `"Hello World"` to fit in rectangle 200x100
selected_size = 1
for size in range(1, 150):
    title_font = ImageFont.FreeTypeFont(font_path, size=size)
    w, h = title_font.getsize(title_text)
    
    if w > 200 or h > 100:
        break
        
    selected_size = size
    
# draw text in center of rectangle 200x100        
title_font = ImageFont.FreeTypeFont(font_path, size=selected_size)

draw.text((200-(w//2), 150-h//2), title_text, fill='red', font=title_font)

display(img)

请注意,使用换行符后,文本的大小不会正确调整,也不会居中。显然

.getsize()
方法不能很好地处理换行符。

我正在使用 Pillow 版本 7.1.2 并在 Google Colab Notebook 中运行所有这些(这就是我运行

display(img)
的原因)。

我可以做什么来解决这个问题?我的最终目标是使用 Python 为游戏创建卡片。有些卡片有两个单词,而其他卡片只有一个单词。我希望我的代码能够调整文本大小并使文本居中,无论字数有多少。

编辑:经过一些测试,我注意到

.getsize()
将字符串
"Hello\nWorld"
视为单行文本而不是两行。我的问题可能是:如何获取带换行符的文本的大小?

python python-imaging-library
2个回答
2
投票

我已经找到解决办法了。最终代码如下所示:

title_text = "Hello\nWorld"

img = Image.new(size=(400, 300), mode='RGB')
draw = ImageDraw.Draw(img)
font_path = "/content/Charlie don't surf.ttf"

# draw white rectangle 200x100 with center in 200,150
draw.rectangle((200-100, 150-50, 200+100, 150+50), fill='white')
draw.line(((0, 150), (400, 150)), 'gray')
draw.line(((200, 0), (200, 300)), 'gray')

# find font size for text `"Hello World"` to fit in rectangle 200x100
selected_size = 1
for size in range(1, 150):
    title_font = ImageFont.FreeTypeFont(font_path, size=size)
    #w, h = title_font.getsize(title_text)
    w, h = draw.textsize(title_text, title_font)
    
    if w > 200 or h > 100:
        break
        
    selected_size = size
    
# draw text in center of rectangle 200x100        
title_font = ImageFont.FreeTypeFont(font_path, size=selected_size)

draw.text((200-(w//2)+5, 150-h//2), title_text, fill='red', font=title_font, align = "center")

display(img)

最终结果是:

我使用了在此页面上找到的资源。更具体地说,我发现您可以使用

draw.textsize(title_text, title_font)
来获得更精确的文本大小,尤其是当它有换行符时。


0
投票

只需对上面的代码进行一点更新,因为

w, h = 绘制.textsize(标题文本, 标题字体)

已弃用。只需使用

_, _, w, h = draw.textbbox((0, 0), title_text, font=title_font)

相反

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