我试着用枕头把文本放在盒子的中心.我已经按照这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)

Note that the text is centered and resized as desired

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

但如果我把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)

enter image description here

请注意,使用换行符时,文本的大小没有正确调整,也没有居中.显然,.getsize()方法不能很好地处理换行.

我正在使用Pillow 7.1.2版本,并在Google Colab笔记本中运行所有这些(这就是我运行display(img)的原因).

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

编辑:经过一些测试,我注意到.getsize()将字符串"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)
    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)

最终结果是:

enter image description here

我使用了在this page上找到的资源.更具体地说,我发现可以使用draw.textsize(title_text, title_font)来获得更精确的文本大小,尤其是当它有换行符时.

Python相关问答推荐

Julia CSV for Python中的等效性Pandas index_col参数

当独立的网络调用不应该互相阻塞时,'

python中字符串的条件替换

提取相关行的最快方法—pandas

合并帧,但不按合并键排序

在matplotlib中删除子图之间的间隙_mosaic

dask无groupby(ddf. agg([min,max])?''''

寻找Regex模式返回与我当前函数类似的结果

如何在Gekko中使用分层条件约束

如何使用matplotlib查看并列直方图

在第一次调用时使用不同行为的re. sub的最佳方式

Pandas:将值从一列移动到适当的列

设置索引值每隔17行左右更改的索引

Pythonquests.get(Url)返回Colab中的空内容

如何将验证器应用于PYDANC2中的EACHY_ITEM?

按最大属性值Django对对象进行排序

了解如何让库认识到我具有所需的依赖项

打印:添加具有不同填充 colored颜色 的矩形

极点在没有Groupby的情况下聚合

PYTORCH-张量问题-Mat1和Mat2形状不能相乘(8x10和8x8)