因为给nonebot机器人做了个RPG小游戏的插件,文本文字的形式过于乏味:
然后想用python直接生成个图片,简洁美观:
代码如下,其中带"《===" 注释的为便捷自定义参数
from PIL import Image,ImageDraw,ImageFont
from matplotlib.pyplot import title
import math
def main():
width = 310
height = 200
title_size = 36 # 标题文字大小 《===
nr_size = 24 # 内容文字大小 《===
title_fnt = r'wqy-microhei.ttc' # 标题的字体 《===
nr_fnt = r'wqy-microhei.ttc' # 内容的字体 《===
title_txt = "背包"
nr = {"苹果":"2","苹果45":"2","菜刀":"1","失落的漆黑之剑":"1","河边捡的失落的漆黑之剑":"1","河边捡的失落的漆黑之剑":"19999999999999"}
fnt = ImageFont.truetype(title_fnt,size=title_size)
fnt_nr = ImageFont.truetype(nr_fnt,size=nr_size)
title_lay_top = 5 # 标题文本距离图片顶部的距离 《===
rectangle1_lay_left_right = 15 # 标题下方的装饰方框的左右边距 《===
rectangle1_lay_top = 5 # 标题下方的装饰方框的上边距 《===
rectangle1_height = 15 # 标题下方的装饰方框的高度 《===
rectangle3_lay_top = 10 # 内容方框的顶部边距 《===
rectangle3_lay_bottom = 10 # 内容方框的底部边距 《===
rectangle3_lay_left_right = 10 # 内容方框的左右边距 《===
rectangle3_lay_padding = 5 # 内容方框的内边距 《===
nr_lay_bottom = 5 # 内容文本的底部边距 《===
nr_layout_weight = "3:2" # 两部分内容占用空间比例 《===
bl1 = int(nr_layout_weight[0])
bl2 = int(nr_layout_weight[2])
bl_ans = bl1 + bl2
nr_height = fnt_nr.getbbox("测试文字占用尺寸用")[3]
nr_num = len(nr.keys())
rectangle_left_top_a = math.ceil(rectangle1_height/2) # 左上角装饰方框的边长
heigh_img = title_lay_top + fnt.getbbox(title_txt)[3] + rectangle1_lay_top + rectangle1_height
height = heigh_img + rectangle3_lay_top + rectangle3_lay_bottom + rectangle3_lay_bottom*2 + nr_height*nr_num + (nr_num-1)*nr_lay_bottom
im = Image.new("RGB",(width,height),color=(238,239,241))
draw = ImageDraw.Draw(im)#创建一个绘画对象
box_txt = fnt.getbbox(title_txt)
# 绘制标题
draw.text((im.size[0]/2-box_txt[2]/2,title_lay_top),title_txt,fill=(33,51,72),font=fnt)
# 绘制装饰框1
rectangle1_hang = title_lay_top + int(box_txt[3]) + rectangle1_lay_top # 标题下边框顶部所在行
draw.rectangle(((rectangle1_lay_left_right,rectangle1_hang),(width-rectangle1_lay_left_right,rectangle1_hang + rectangle1_height)),fill=None,outline=(33,51,72),width=3) # 绘制标题下边框
# 绘制装饰框2
draw.rectangle(((rectangle1_lay_left_right-rectangle_left_top_a,rectangle1_hang-rectangle_left_top_a),(rectangle1_lay_left_right+rectangle_left_top_a,rectangle1_hang+rectangle_left_top_a)),fill=None,outline=(226,160,11),width=3)
# 绘制内容框
rectangle3_hang = rectangle1_hang + rectangle1_height + rectangle3_lay_top
rectangle3_height = rectangle3_lay_bottom*2 + nr_height*nr_num + (nr_num-1)*nr_lay_bottom
draw.rectangle(((rectangle3_lay_left_right,rectangle3_hang),(width-rectangle3_lay_left_right,rectangle3_hang+rectangle3_height)),fill=None,outline=(33,51,72),width=2)
#内容文字绘制
nr_hang = rectangle3_hang + rectangle3_lay_padding + nr_height/2
nr_lie = width - rectangle3_lay_left_right*2 -rectangle3_lay_padding*2
nr1_X = math.ceil(nr_lie/bl_ans*bl1/2) + rectangle3_lay_left_right + rectangle3_lay_padding
nr2_X = math.ceil(nr_lie/bl_ans*bl1) + math.ceil(nr_lie/bl_ans*bl2/2) + rectangle3_lay_left_right + rectangle3_lay_padding
for i in nr.keys():
box_txt2_1 = fnt_nr.getbbox(i)
box_txt2_2 = fnt_nr.getbbox(nr[i])
#自适应调整文字大小
temp_fnt = fnt_nr
temp_size = nr_size
while(box_txt2_1[2]>=math.ceil(nr_lie/5*3)-2 and temp_size > 1):
temp_size = temp_size-1
temp_fnt = ImageFont.truetype(nr_fnt,size=temp_size)
box_txt2_1 = temp_fnt.getbbox(i)
fnt_nr1 = temp_fnt
temp_fnt = fnt_nr
temp_size = nr_size
while(box_txt2_2[2]>=math.ceil(nr_lie/5*2)-2 and temp_size > 1):
temp_size = temp_size-1
temp_fnt = ImageFont.truetype(nr_fnt,size=temp_size)
box_txt2_2 = temp_fnt.getbbox(nr[i])
fnt_nr2 = temp_fnt
draw.text((nr1_X-box_txt2_1[2]/2,nr_hang-box_txt2_1[3]/2),i,fill=(33,51,72),font=fnt_nr1)
draw.text((nr2_X-box_txt2_2[2]/2,nr_hang-box_txt2_2[3]/2),nr[i],fill=(33,51,72),font=fnt_nr2)
nr_hang = nr_hang + nr_height + nr_lay_bottom
im.show()#调用默认图片查看器查看
# im.save('1.jpg')
if __name__=="__main__":
main()