python生成模拟微信气泡图片
创始人
2024-04-09 01:17:58

0. 起因

众所周知,借刀杀人最为致命,聊天也是如此。

最近我的群聊画风逐渐变味:

在这里插入图片描述

当然,这种图片的生产成本很低,只需在设置页关闭昵称显示,把聊天背景重置为灰色,然后利用截图工具截图,最后保存到手机里,添加到表情包库中即可。

然而微信头像是会更改的,人的精力也是有限的,经过了两天的狂欢后,我们逐渐意识到这种文化的短期性。

但是,无所谓,我会出手!我灵光一闪,只要把数据来源从截图变成生成,那么即使微信头像更改,也可以随时替换,如此,便有了此文。

1. 准备工作

技术栈:Python内置的 PIL(Pillow)库

头像文件:可以直接从微信中保存,我们给它命名为 logo.jpg

主脚本文件:main.py

(为了方便脚本编写,main.pylogo.jpg 放置在同一目录下)

提示:下面两张表是写完后折回来后补的

输入参数含义默认
text要生成的话“Hello World”
logo_path要生成的气泡用的头像“logo.jpg”
save_path图片的保存路径及文件名“save.jpg”
font_path字体的路径“fonts/msyhl.ttc”
font_size字体的大小25
space_lengh间隙的长度20
bg_height背景的高度64
输出含义
savepath一张图片文件

2. 脚本设计与编写

我们可以从微信上面随便截一下,看看大概的长度。

在这里插入图片描述
通过状态栏的提示可知:370x50 为这张图片的大小。

我们取一个看起来舒服一点的值,就 64 吧,作为我们绘图的高度,同时我们选择微软雅黑作为。

至于宽度,我们现在已知左边的头像是一个正方形,正方形和右边的白色背景起泡之间的距离为 20,起泡的长度又视文字的长度而定,所以背景的宽度也是不定的。

所以我们下一步是,如何估算出 文字生成后的大概大小?

2.1 估算文字生成后的大概大小

通过阅读博文:使用Python PIL库获取某个字体渲染后的文本的宽高(应用于检测翻译后的文本是否长度过长)

我们找到了方案,就是如下的一段函数:

fontsize=26
white = (255,255,255)
def get_font_render_size(text):canvas = Image.new('RGB', (2048,2048))draw = ImageDraw.Draw(canvas)monospace = ImageFont.truetype("msyh.ttc", fontsize)draw.text((0, 0), text, font=monospace, fill=white)bbox = canvas.getbbox()# 宽高size = (bbox[2] - bbox[0], bbox[3] - bbox[1])return size
# ————————————————
# 版权声明:本文为CSDN博主「林新发」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
# 原文链接:https://blog.csdn.net/linxinfa/article/details/116527440

具体原理可以去对应博文查看,这里就直接投入使用啦。

我们进行轻微改动后就可以得到函数,返回值为一个元组(宽, 高)

def get_font_render_size(text, font_path, font_size):""":param text: 文字:param font_path: 字体路径:param font_size: 字体大小:return: tuple 宽高"""canvas = Image.new('RGB', (2048, 2048))ImageDraw.Draw(canvas).text((0, 0), text, font=ImageFont.truetype(font_path, font_size))bbox = canvas.getbbox()return bbox[2] - bbox[0], bbox[3] - bbox[1]
# 计算文字渲染后的长度
text_width, text_height = get_font_render_size(text, font_path, font_size)

之后我们用text_width表示文字渲染后的长度

2.2 绘制背景

# 定义背景宽度
bg_width = text_width + space_length

bg_height作为输入参数出现,无需定义。

# 生成背景
bg_img = Image.new(mode='RGB', size=(bg_width + 100, bg_height), color="#F5F5F5")

2.3 绘制头像

#读取头像文件,并绘制头像到背景图片
logo = Image.open(logo_path, mode="r")
logo = logo.resize((bg_height, bg_height))
bg_img.paste(logo, (0, 0))

2.4 绘制气泡

2.4.1 绘制圆角矩形

x, y, w, h, r = bg_height + space_length, 0, text_width + space_length * 1.5, bg_height, space_length
fill_color = "#FFFFFF"
draw_object = ImageDraw.Draw(bg_img)draw_object.ellipse((x, y, x + r, y + r), fill=fill_color)
draw_object.ellipse((x + w - r, y, x + w, y + r), fill=fill_color)
draw_object.ellipse((x, y + h - r, x + r, y + h), fill=fill_color)
draw_object.ellipse((x + w - r, y + h - r, x + w, y + h), fill=fill_color)draw_object.rectangle((x + r / 2, y, x + w - (r / 2), y + h), fill=fill_color)
draw_object.rectangle((x, y + r / 2, x + w, y + h - (r / 2)), fill=fill_color)

2.4.2 绘制三角形 (对话的哪个尖尖)

draw_object.polygon([(bg_height + space_length / 2, bg_height / 2),(bg_height + space_length, bg_height / 2 - space_length / 2),(bg_height + space_length, bg_height / 2 + space_length / 2),
], fill="#FFFFFF")

2.4.3 绘制字体

draw_object.text((bg_height + space_length + 15, (bg_height - 25) / 2 - 5 - 1),text, fill=0, font=ImageFont.truetype(font_path, font_size))

2.5 保存图片

bg_img.save(save_path)

3. 效果展示

在这里插入图片描述

4. 成品代码

from PIL import Image, ImageDraw, ImageFontdef get_font_render_size(text, font_path, font_size):""":param text: 文字:param font_path: 字体路径:param font_size: 字体大小:return: tuple 宽高"""canvas = Image.new('RGB', (2048, 2048))ImageDraw.Draw(canvas).text((0, 0),text, font=ImageFont.truetype(font_path, font_size))bbox = canvas.getbbox()return bbox[2] - bbox[0], bbox[3] - bbox[1]def main(text="Hello World", logo_path="logo.jpg", save_path="save.jpg",font_path="fonts/msyhl.ttc", font_size=25, space_length=20,bg_height=64):# 计算文字渲染后的长度text_width, text_height = get_font_render_size(text, font_path, font_size)# 定义背景宽度bg_width = text_width + space_length# 生成背景bg_img = Image.new(mode='RGB', size=(bg_width + 100, bg_height), color="#F5F5F5")# 读取头像文件,并绘制头像到背景图片logo = Image.open(logo_path, mode="r")logo = logo.resize((bg_height, bg_height))bg_img.paste(logo, (0, 0))# 绘制气泡## 1. 绘制圆角矩形x, y, w, h, r = bg_height + space_length, 0, text_width + space_length * 1.5, bg_height, space_lengthfill_color = "#FFFFFF"draw_object = ImageDraw.Draw(bg_img)draw_object.ellipse((x, y, x + r, y + r), fill=fill_color)draw_object.ellipse((x + w - r, y, x + w, y + r), fill=fill_color)draw_object.ellipse((x, y + h - r, x + r, y + h), fill=fill_color)draw_object.ellipse((x + w - r, y + h - r, x + w, y + h), fill=fill_color)draw_object.rectangle((x + r / 2, y, x + w - (r / 2), y + h), fill=fill_color)draw_object.rectangle((x, y + r / 2, x + w, y + h - (r / 2)), fill=fill_color)## 2. 绘制三角形 (对话的哪个尖尖)draw_object.polygon([(bg_height + space_length / 2, bg_height / 2),(bg_height + space_length, bg_height / 2 - space_length / 2),(bg_height + space_length, bg_height / 2 + space_length / 2),], fill="#FFFFFF")## 3. 绘制字体draw_object.text((bg_height + space_length + 15, (bg_height - 25) / 2 - 5 - 1),text, fill=0, font=ImageFont.truetype(font_path, font_size))bg_img.save(save_path)if __name__=="__main__":main("Hello World") # 更改此处文字即可。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...