小知识,大挑战!本文正在参与“ 程序员必备小知识 ”创作活动
在本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
前面说说
本文是对两年前文章你还在@微信官方?我来教你用Python生成你想要的微信头像 的一个优化,同时更新了素材。
提前祝大家国庆节快乐。
我记得当时事情是这样的,那是19年的国庆,举国欢庆建国70周年,不知怎么的,朋友圈出现了很多@微信官方
给自己头像加五星红旗。 差点点信以为真,其实是假的,所以,咱还是老老实实自己动手。
看到这,如果你只是想快速生成一个庆国庆的微信头像,不想了解相关技术,很简单,直接点击下方卡片,关注公众号:外卖电影娱乐通,菜单栏点击国庆头像
,即可生成。
当时经过需求分析,最终选择了图像合并的方法,今天主要基于之前程序做了如下几点优化:
1、增加图片模板,目前有6个模板
2、控制台增加文字菜单,自动读取头像、模板文件,想选谁就选谁
3、增加GUI程序软件界面,自己选择要上传什么头像图片,选择什么模板
4、增加web端口,自己选择要上传什么头像图片,选择什么模板
最近悟出个道理,文章太长其实不利于大家学习、阅读,在这个碎片化学习的时代,除了学生,可能很难有人能专心花几个小时学习,更别说是对着微信技术文章了,密密麻麻的代码也能把你给看昏。
所以后面每次有项目,我会尽量分块来分享,做成一个个小系列,这样对于系列里的每一部分我也能更仔细的去打磨,毕竟要做到大家都能读懂嘛。
微信头像处理系列也将分为很多篇,比如现在就有明确的三篇:
- 庆国庆微信头像处理这么简单?几行代码一秒出图
- 给庆国庆微信头像处理程序写个GUI界面
- flask实现庆国庆微信头像处理程序web借口
庆国庆微信头像处理这么简单?几行代码一秒出图
现在我们要写的是最简单也是最核心的部分,根据需求编写代码,再啰嗦下需求,并进行功能拆分:
# 需求:将模板图片粘贴到微信头像上,保存处理好的文件
需求功能拆分:
1、读取微信头像和模板图片
2、调整两个图像尺寸为一致(700*700)
3、将模板图片粘贴到微信头像上
4、保存处理好的文件
复制代码
根据上面的功能拆分,我们可以一步步实现代码。 0)导入相关包
from PIL import Image
复制代码
1)读取微信头像和模板图片
# 打开图片模版
img1 = Image.open("./img/7.jpg")
img1 = img1.convert('RGBA')
# 打开原来的微信头像
img2 = Image.open("./img/Avatar/old/3.jpeg")
img2 = img2.convert('RGBA')
复制代码
读取图片我们直接利用PIL中image对象的open函数即可,只需传入图片路径即可。
然后我们还调用convert
函数将图片颜色格式转为了RGBA
,这样的好处一是统一图片颜色格式,方便后面图片合并,另外就是RGBA是有透明通道的真彩色模式,合并时我们可以设置mask,那么合并时透明部分就不会被复制粘贴到原图像上了,。其他模式还有:
- RGB : 24位彩色图像
- 1 :1位像素,黑白,存储的时候每个像素存储为8bit
- L :8位像素,灰色
2)调整两个图像尺寸为一致(700*700)
size = (700, 700)
if img1.size != size: # 判断图片大小,统一改为 700*700
# 修改图片尺寸
img1.thumbnail(size)
if img2.size != size: # 判断图片大小,统一改为 700*700
# 修改图片尺寸
img2.thumbnail(size)
复制代码
这里我们调用Image中的size属性,获取图片的尺寸,长*宽(像素),然后判断并统一修改尺寸,这里我们使用了thumbnail函数对图片进行缩放,这个函数会根据我们设置的size进行长宽等比例缩放,图片内容不会变形。
当然我们也可以利用resize这个函数重新设置size,但是可能会导致图片内容变形。
3)将模板图片粘贴到微信头像上
# 图片粘贴选区
loc = (0, 0, 700, 700)
# 将img1 粘贴到 img2
img2.paste(img1, loc, img1)
复制代码
两个图像的合并,我们这里的操作就是直接将模板图片粘贴到原微信头像上,这里我们利用了Image中paste函数,有三个参数,第一个是被粘贴的图片,第二个是粘贴的位置,可以设置左上角像素坐标(x,y),也可以设置粘贴区域(a,b,c,d)。
还有一个可选参数mask,设置遮罩,设置后图片粘贴会按遮罩指定区域进行粘贴,在RGBA模式图片下,alpha(透明通道)波段用作遮罩,这样粘贴模板到原微信头像上时,模板中透明部分就不会被粘贴过去了。
4)保存处理好的文件
img2.show() # 显示图片
img2.save("./img//Avatar/new/3.png") # 保存生成的头像图片
复制代码
保存图片我们利用的是Image的save函数,直接指定保存路径即可,另外我们还调用了show函数来显式的展现处理后的图片。
通过上面四步处理,我们就完成了庆国庆微信头像的生成。
完成第一次优化,程序控制台输出菜单,用户自己选择处理哪个微信头像,选择哪个模板,直接上代码。
第一版,手动输入原微信头像目录,并固定print模板名字
from PIL import Image
import os
"""
需求:给图片右下角添加中国国旗,欢迎国庆,表达对祖国的热爱
"""
# 定义一个图片处理类
class Picture:
'''
打印菜单
'''
def print_menu_national_day_picture(self):
# 1、打印菜单
print('******欢迎进入国庆微信头像生成程序******')
# 首先输入原微信头像地址
old_img_path = input('******请输入你的微信头像路径:')
while not os.path.isfile(old_img_path):
print('你输入的图片路径不存在,请重新输入')
old_img_path = input('******请输入你的微信头像路径:')
while True:
# 这里我们固定几个模板
print('******请选择图像模板,目前的模板设计类型有******')
print('***1、国旗')
print('***2、透明国旗')
print('***3、祖国生日快乐')
print('***4、庆国庆')
print('***5、给你小红旗')
print('***6、天安门')
print('***7、天安门国旗')
print('******您还可以输入:0,直接退出程序******')
img_template_st = input('请输入您的选择:(输入数字序号即可)')
# 2、判断输入情况
if img_template_str == '1':
return old_img_path, './img/1.png'
elif img_template_str == '2':
return old_img_path, './img/2.png'
elif img_template_str == '3':
return old_img_path, './img/3.png'
elif img_template_str == '4':
return old_img_path, './img/4.png'
elif img_template_str == '5':
return old_img_path, './img/5.png'
elif img_template_str == '6':
return old_img_path, './img/6.png'
elif img_template_str == '7':
return old_img_path, './img/7.png'
elif img_template_str == '0': # 退出,返回''空字符串
print('******您已退出国庆头像P图处理程序******')
return '', ''
else:
print('没有你输入的头像模板:%s'% img_template_str)
'''
处理合并图片
'''
def handle_national_day_picture(self):
# 获取原微信头像路径和模板路径
old_img_path, img_template_path = self.print_menu_national_day_picture()
if img_template_path == '': # 表示用户选择了退出程序 0
return '' # 直接return结束程序
# 否则开始进行处理
# 打开图片模版
img1 = Image.open(img_template_path)
img1 = img1.convert('RGBA')
if img1.size != (700, 700): # 判断图片大小,统一改为 700*700
# 修改图片尺寸
size = (700, 700)
img1.thumbnail(size)
# 打开原来的微信头像
img2 = Image.open(old_img_path)
img2 = img2.convert('RGBA')
print('img2', img2.size)
if img2.size != (700, 700): # 判断图片大小,统一改为 700*700
# 修改图片尺寸
size = (700, 700)
img2.thumbnail(size)
# 图片粘贴选区
loc = (0, 0, 700, 700)
# 将img1 粘贴到 img2(模板图片在上)
img2.paste(img1, loc, img1)
img2.show() # 显示图片
old_name = os.path.basename(old_img_path).split('.')[0]
template_name = os.path.basename(img_template_path).split('.')[0]
new_pic_path = "./img/Avatar/new/{0}_{1}.png".format(old_name, template_name)
img2.save(new_pic_path) # 保存生成的头像图片
print('******新头像文件目录:%s******'%new_pic_path )
print('******恭喜你成功生成了属于自己的国庆微信信头像******')
return 'success'
复制代码
第二版,自动读取文件目录,打印头像和模板目录,选择序号即可
from PIL import Image
import os
"""
需求:给图片右下角添加中国国旗,欢迎国庆,表达对祖国的热爱
"""
# 定义一个图片处理类
class Picture:
# 模板名称:序号
template_dicts = {
'国旗':'1',
'透明国旗':'2',
'祖国生日快乐':'3',
'庆国庆':'4',
'给你小红旗':'5',
'天安门':'6',
'天安门国旗':'7'
# 更多模板可以自己添加
# 格式 模板名称:序号,模板文件名:序号.png
}
# 文件目录路径
template_root_path = './img/'
wx_avatar_old_path = './img/Avatar/old/'
wx_avatar_new_path = './img/Avatar/new/'
# 图片文件后缀,如有其他格式可以添加
image_suffixes = {'png', 'jpg', 'jpeg', 'gif', 'JPG', 'PNG', 'GPEG', 'GIF'}
'''
打印菜单
'''
def print_menu_national_day_picture(self):
'''
1、打印菜单
'''
print('******欢迎进入国庆微信头像生成程序******')
'''
2、原微信头像打印+选择
'''
print('******请选择您要处理的微信头像图片名******')
# 1)获取微信原头像目录下所有图片文件,并打印出文件名
index = 1
temp_dict = {}
for i in os.listdir(self.wx_avatar_old_path):
file_suffix = i.split('.')[1]
if file_suffix in self.image_suffixes: # 过滤非图片文件
print('******{0}、{1}'.format(index, i))
temp_dict = {str(index): i}
index+=1
print('******您还可以输入:0,直接退出程序******')
# 2)用户选择图像
old_img_index = input('******请输入您要处理的微信头像序号(输入数字序号即可):')
# 是否退出程序
if old_img_index == '0':
print('******您已退出国庆头像P图处理程序******')
return '', ''
# 文件是否存在
while old_img_index not in temp_dict:
print('您输入的序号不存在,请重新输入')
old_img_index = input('******请输入您要处理的微信头像序号(输入数字序号即可):')
old_img_path = self.wx_avatar_old_path + temp_dict[old_img_index]
'''
3、模板打印+选择
'''
while True:
# 1)打印已存在模板
print('******请选择图像模板,目前的模板设计类型有******')
# 遍历字典自动打印模板名称
for k,v in self.template_dicts.items():
print('******{1}、{0}'.format(k, v))
# 2)用户选择模板
img_template_str = input('请输入您想用的模板:(输入数字序号即可)')
# 判断用户输入是否有效
while img_template_str not in self.template_dicts.values():
print('您输入的序号不存在,请重新输入')
img_template_str = input('******请输入您想用的模板:(输入数字序号即可)')
# 3)根据用户输入,返回原图片路径和模板路径
if img_template_str in self.template_dicts.values():
return old_img_path, self.template_root_path + img_template_str + '.png'
else:
print('没有你输入的头像模板序号:%s'% img_template_str)
'''
处理合并图片
'''
def handle_national_day_picture(self):
# 1) 获取原微信头像路径和模板路径
old_img_path, img_template_path = self.print_menu_national_day_picture()
if img_template_path == '': # 表示用户选择了退出程序 0
return '' # 直接return结束程序
# 2)开始进行处理
# 打开图片模版
img1 = Image.open(img_template_path)
img1 = img1.convert('RGBA')
size = (700, 700) # 判断图片大小,统一改为 700*700
if img1.size != size:
# 修改图片尺寸
img1.thumbnail(size)
# 打开原来的微信头像
img2 = Image.open(old_img_path)
img2 = img2.convert('RGBA')
if img2.size != size:
# 修改图片尺寸
img2.thumbnail(size)
# 3)图片粘贴选区
loc = (0, 0, 700, 700)
# 将img1 粘贴到 img2(模板图片在上)
img2.paste(img1, loc, img1)
img2.show() # 显示图片
old_name = os.path.basename(old_img_path).split('.')[0]
# 取出原头像名称和模板名称,合起来作为新头像的名称
template_name = os.path.basename(img_template_path).split('.')[0]
new_pic_path = self.wx_avatar_new_path + "{0}_{1}.png".format(old_name, template_name)
img2.save(new_pic_path) # 保存生成的头像图片
print('******新头像文件目录:%s******'%new_pic_path )
print('******恭喜你成功生成了属于自己的国庆微信信头像******')
print('')
print('******你可以选择继续处理其他头像,或者输入0,退出程序')
print('')
print('')
return 'success'
复制代码
实力化一个对象,然后调用函数
t0 = Picture()
while True:
# 开始程序
sucess = t0.handle_national_day_picture()
# ./img/Avatar/old/3.jpeg
if sucess == '':
print('******感谢你的使用,国庆微信头像制作程序已结束******')
break
复制代码
生成效果图
素材文件获取方式:直接网络上找下,然后处理下即可,或者加我微信pythonbrief,备注:掘金,即可获取。
下集预告
给庆国庆微信头像处理程序写个GUI界面。
效果图如下(类似哈~):