PIL库 : 居中对齐写入文本(英文 / 中文)

英文 文本 的居中对齐


from PIL import Image, ImageDraw

W, H = (600,360)
msg_english = '''
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
'''

im = Image.new("RGBA",(W,H),"white")
draw = ImageDraw.Draw(im)
w, h = draw.textsize(msg_english)
draw.text(((W-w)/2,(H-h)/2), msg_english, fill="black")
im.show()
im.save("hello.png", "PNG")

输出:
在这里插入图片描述

中文 文本 的居中对齐

一、 我的理解: 占用的像素大小 sum = font_size * len(str)
我测试了结果能够较为直观的 居中显示,但不是严格的,所以上面的公式可能不是严格的数学定义,希望知道的朋友指出来。

from PIL import Image, ImageDraw,ImageFont
W, H = (600,360)
msg_hanzi = '''作者否认所有有关的保证'''
im = Image.new("RGBA",(W,H),"white")
draw = ImageDraw.Draw(im)
font_size = 32
fillColor = "blue"  # 设置字体颜色
setFont = ImageFont.truetype('C:/windows/fonts/Dengl.ttf', font_size) #设置字体以及字体大小
w, h = len(msg_hanzi)*font_size,font_size # 计算汉字占用的像素大小
draw.text(((W-w)/2, (H-h)/2), msg_hanzi, font=setFont,fill = fillColor)  # 利用ImageDraw的内置函数,在图片上写入文字
im.show()
im.save("hello.png", "PNG")

输出:
在这里插入图片描述

二,这里有个问题,如果 汉字字符串是一大串,该怎么处理呢?,比如下面的示例,
我的思路是: 将字符串分割成列表,然后再 每行 按照上面的规则写入。


from PIL import Image, ImageDraw,ImageFont
W, H = (600,360)
msg_hanzi = '''
1,秘密实验室AB和作者否认所有有关的保证
2,本软件,包括所有隐含的适销性保证和
3,健康。在任何情况下,秘密实验室AB或作者不承担任何责任
4,任何特殊、间接或结果性损害赔偿或任何损害赔偿
5,任何因使用、数据或利润的损失而造成的损失,不论是在
6,因合同、过失或其他侵权行为而引起的诉讼本软件的使用或性能的
'''

im = Image.new("RGBA",(W,H),"white")
draw = ImageDraw.Draw(im)
font_size = 16
fillColor = "blue"  # 设置字体颜色
setFont = ImageFont.truetype('C:/windows/fonts/Dengl.ttf', font_size) #设置字体以及字体大小
msg_list = msg_hanzi.split('\n')  # 分割字符串成列表
h =  font_size * len(msg_list)
for i in range(len(msg_list)):
    w = len(msg_list[i])*font_size
    draw.text(((W-w)/2, (H-h)/2 + i*font_size ), msg_list[i], font=setFont,fill = fillColor)  
im.show()
im.save("hello.png", "PNG")

输出:
在这里插入图片描述
三, 上面的输出,行间距太小了,我做了点代码改动,增加了行间距


from PIL import Image, ImageDraw,ImageFont
W, H = (600,360)
msg_hanzi = '''
1,秘密实验室AB和作者否认所有有关的保证
2,本软件,包括所有隐含的适销性保证和
3,健康。在任何情况下,秘密实验室AB或作者不承担任何责任
4,任何特殊、间接或结果性损害赔偿或任何损害赔偿
5,任何因使用、数据或利润的损失而造成的损失,不论是在
6,因合同、过失或其他侵权行为而引起的诉讼本软件的使用或性能的
'''

im = Image.new("RGBA",(W,H),"white")
draw = ImageDraw.Draw(im)
font_size = 16
fillColor = "blue"  # 设置字体颜色
setFont = ImageFont.truetype('C:/windows/fonts/Dengl.ttf', font_size) #设置字体以及字体大小
msg_list = msg_hanzi.split('\n')  # 分割字符串成列表
spaceNum = 8 # 行间距 设置为8px
h = ( font_size + spaceNum)  * len(msg_list)
for i in range(len(msg_list)):
    w = len(msg_list[i])*font_size
    draw.text(((W-w)/2, (H-h)/2 + i*( font_size + spaceNum)  ), msg_list[i], font=setFont,fill = fillColor)  # 利用ImageDraw的内置函数,在图片上写入文字
im.show()
im.save("hello.png", "PNG")

这样看起来比上面的好多了
在这里插入图片描述
四, 虽然看起来还不错,但是我觉得还是很乱,我想放弃绝对的居中对齐,选择左对齐,但是相对居中的方式输出


from PIL import Image, ImageDraw,ImageFont
W, H = (600,360)
msg_hanzi = '''
1,秘密实验室AB和作者否认所有有关的保证
2,本软件,包括所有隐含的适销性保证和
3,健康。在任何情况下,秘密实验室AB或作者不承担任何责任
4,任何特殊、间接或结果性损害赔偿或任何损害赔偿
5,任何因使用、数据或利润的损失而造成的损失,不论是在
6,因合同、过失或其他侵权行为而引起的诉讼本软件的使用或性能的
'''

im = Image.new("RGBA",(W,H),"white")
draw = ImageDraw.Draw(im)
font_size = 16
fillColor = "blue"  # 设置字体颜色
setFont = ImageFont.truetype('C:/windows/fonts/Dengl.ttf', font_size) #设置字体以及字体大小
msg_list = msg_hanzi.split('\n')  # 分割字符串成列表
max_para = len(max(msg_list))  # 选取列表中最长的那一行字符串为行写入坐标的基础
spaceNum = 8
h = ( font_size + spaceNum)  * len(msg_list)
w = max_para * font_size
for i in range(len(msg_list)): #这样的话,每次写入,行坐标就不动了,只动列坐标
    draw.text(((W-w)/2, (H-h)/2 + i*( font_size + spaceNum)  ), msg_list[i], font=setFont,fill = fillColor)  # 利用ImageDraw的内置函数,在图片上写入文字
im.show()
im.save("hello.png", "PNG")

输出:
这就输最后的结果了。
在这里插入图片描述

欢迎讨论怎么更好的汉语写入图片

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚂蚁小兵

慢慢长夜磨一章好文章,费烟!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值