基于PIL对图片进行修改,在前一文中是对通过对已定义的表情包模板,在群聊中进行表情包生成,但总定义模板还是过于麻烦,于是升级为输入图片即可添加文字。前文网址:https://blog.csdn.net/qq_45720608/article/details/120026989
通过对nonebot2机器人发送图片或动图,让它对表情包添加文字。
新增函数
# 定义两个函数,修改前文函数输入,改为图片生成是传入文本及图片地址。
def get_im(keys):
keys = urllib.parse.quote(keys)
path = f'/home/xiaochen/database/image/{keys}.jpg'
return path
# 定义文字写入图片下方15%处,定义字体选择大小,得出输入多少字较为合适
def get_im_infor(path):
im = Image.open(path)
w, h = im.size
n = int(0.145 * h)
if n >= 25:
x = int(w/25)
else:
x = int(w / n)
return x
对前文原有图片生成函数进行修改:
# 定义一个函数,def get_express_img(path, text),将之前的keys修改为传入图片地址。最终返回图片生成的地址
def get_express_img(path, text):
im = Image.open(path)
w, h = im.size
n = int(0.145*h)
# 对图片中的字体大小进行定义
if n >= 25:
font = ImageFont.truetype(f'/home/xiaochen/database/Fronts/msyh.ttc', 25)
else:
font = ImageFont.truetype(f'/home/xiaochen/database/Fronts/msyh.ttc', n)
t_w, t_h = font.getsize(text)
# print(t_w, t_h)
text_size = (w, t_h + 20)
bg = Image.new('RGB', text_size, color='white')
draw = ImageDraw.Draw(bg)
text_coordinate = ((w - t_w) / 2, 10)
draw.text(text_coordinate, text, (0, 0, 0), font=font)
f_size = (w, h + t_h)
f = Image.new('RGB', f_size, color='white')
# 判断图片类型,jpg类型为在原有图片下方拼接文字图片,gif为在图片下方写入文字
if '.jpg' in path:
f.paste(im, (0, 0))
f.paste(bg, (0, (h - t_h)))
out_path = f'/home/xiaochen/database/image_express/output.jpg'
f.save(str(out_path))
else:
frames = []
# 定义文字写入位置
text_coordinate1 = ((w - t_w) / 2, 0.85 * h)
for frame in ImageSequence.Iterator(im):
d = ImageDraw.Draw(frame)
# 写入文字
d.text(text_coordinate1, text, (0, 0, 0), font=font)
del d
b = io.BytesIO()
frame.save(b, format="GIF")
frame = Image.open(b)
frames.append(frame)
out_path = f'/home/xiaochen/database/image_express/output.gif'
frames[0].save(out_path, save_all=True, append_images=frames[1:])
return out_path
在前文的基础上,进行代码新增即可。在前文的@expression.got("expression", prompt="生成表情包类型及语句(例如:奥奇1/给我爬)?")async def handle_expression(bot: Bot, event: Event, state: T_State)下新增加一个if判断语句,原有代码归于if ('/' in msg) and (len(msg)<=20)中,因为对nonebot2发送的图片链接长度远大于20。新增代码如下:
else:
if ':image' in msg:
state['expression'] = (msg.split('url=')[-1][:-2])
resp = requests.get(state["expression"])
resp_cont = resp.content
im = Image.open(BytesIO(resp_cont))
format = im.format
if format =='JPEG' or format =='JPG':
state['url'] = f'/home/xiaochen/database/image_express/input.jpg'
im.save(str(state['url']))
else:
state['url'] = f'/home/xiaochen/database/image_express/input.gif'
im.save(str(state['url']), save_all=True)
x = get_im_infor(state['url'])-1
await expression.send(f'可以输入文字了,由于图片尺寸,输入{x}个字效果可能较好:')
await expression.reject()
else:
# 定义一个 state['url']存放图片保存下的地址,在第一次发送图片继续接收文字,最后将本地处理的图片发送
msg = str(state['expression'])
await expression.send(Message(msg))
im_path = state['url']
out_path = get_express_img(im_path, msg)
img = MessageSegment.image(f'file://{out_path}')
await expression.send(img)
在前文的基础上,经过修改升级的表情包插件,希望里面关于PIL的使用对您能有所帮助,原先插件下载https://github.com/PnengChen/nonebot2
如果你热爱nonebot2机器人,可加群:970353786,非诚勿扰。