最近参加了老男孩的一个python训练营,里面某项任务是要求在某个海报模板上批量添加姓名和二维码,生成类似下图的海报。

python批量生成json Python批量生成海报_python批量生成json

图中我用红色方框标记的是需要修改的地方,先来聊下自己的思路:
1.要进行图片操作,要用到pillow模块,可以直接进行文字的添加和图片的合成
2.生成二维码可以用qrcode模块
3.比较麻烦和没有头绪的是怎么去对文字定位,最后借助了PS,下文具体表述。

第一步:

因为自己会点PS,所以先对原图进行了修改,将二维码和姓名直接删掉,没有PS的小伙伴直接用手机上的软化也可以完成,之后保存为海报的模板文件,如下:

python批量生成json Python批量生成海报_二维码_02

第二步,导入模块,第一行是与Pillow有关的模块,第二行是二维码的模块,至于os模块,后文表述

from PIL import Image, ImageDraw, ImageFont
import qrcode
import os

第三步,定义函数,进行图片操作,这里主要用到了打开图片文件、添加文字、保存文件等几个操作

def poster(path, str1):
    '''
    path:海报模板文件路径
    添加的文字
    '''
    png1 = Image.open(path) #打开文件
    draw = ImageDraw.Draw(png1)
    font = ImageFont.truetype(r"C:\Windows\Fonts\STFANGSO.ttf", 40, encoding="utf-8")  # 设置字体
    draw.text((190, 300), str1, font=font, fill='black')  # 添加文字
    img_name = str1 + '.jpg'  # 海报名称 
    png1.save(img_name)  # 保存海报

path:模板文件的路径

str1:要添加的文字

需要注意的是:

1)第6行文件路径可以是相对路径

2)第7行进行添加文字操作

3)第8行设置字体,其中添加的路径是电脑上的绝对路径,需要注意是字体ttf文件的文件名最好在字体文件中文件的属性中查找,否则有可能一直报错找不到文件,如下图所示,40表示字号,可以调整,最后是编码方式,要添加英文的话可以不写,但是中文可能会报错

python批量生成json Python批量生成海报_二维码_03

4)第9行是文字添加,注意第一个参数是添加的位置元组,是指的文字的左上角位置,就是下图画圈的地方,图片左上角的位置是(0,0)第一个参数是横坐标,第二个参数是纵坐标

5)第10行和11行是保存生成的图片

这里很多人会不清楚坐标的怎么确定,比较笨的方法就是一点点试一试,自己比较懒,所以查了下,可以用PS精确确定位置。

1),打开PS-窗口-信息,如下图所示:

python批量生成json Python批量生成海报_生成二维码_04

2)按crtl+R调出标尺,在标尺上右键选择像素:

python批量生成json Python批量生成海报_Image_05

3)此时信息面板显示的鼠标所在位置就是精确的坐标了。

python批量生成json Python批量生成海报_python批量生成json_06

第四步,生成二维码图片,这个是相对比较简单的,代码如下:

QR_name = 'code.jpg'  # 二维码名称
QR_code = qrcode.make(str1)  # 生成二维码
QR_code.save(QR_name)  # 保存二维码

str1:为添加到二维码中的内容,因为需求里面没有二维码内容的要求,所以用添加的名称作为内容;需求里面并没有需要二维码文件,所以把要保存的二维码名称写死了,这样每次生成新的海报时,都会覆盖原有的二维码图片,好处就是最终完成后,只有最后一个二维码图片

第五步,重新打开二维码图片,与添加文字后的海报合成,代码如下:

png_QR = Image.open(QR_name)  # 重新打开二维码图片
png1.paste(png_QR, (35, 595))  # 添加到海报上
png1.save(img_name)  # 保存海报

这里用到了paste()方法,第一个参数是要添加上图片,也就是二维码图片,第二个参数是坐标元组,同样的确定坐标的方法同上。
其实写到这里基本的代码就完成了,但是实际测试中生成的二维码尺寸偏大,所以这里需要调整大小,pillow中有两种方法改变大小,分别是resize和thumbnail,两种方法都可以改变大小,但区别是前者改变大小,但不能改变像素,后者则可以,这里的大小指的是文件的存储大小,所以用resize,相对于压缩了文件,但显示的尺寸是没变的,所以在合成图片之前,先用thumbnail改变了图片像素尺寸,代码如下:

png_QR = Image.open(QR_name)  # 重新打开二维码图片
png_QR.thumbnail((80, 80), Image.ANTIALIAS)  # 改变二维码大小
png_QR.save(QR_name)  # 保存修改尺寸后的二维码

最后一步,也是os模块的作用,估计自己是有点强迫症,我将合成用的二维码图片删掉
os.remove(QR_name) # 删除二维码文件

完成后附上完整的代码:

def poster(path, str1):
    '''
    path:海报模板文件路径
    添加的文字
    '''
    png1 = Image.open(path) #打开文件
    draw = ImageDraw.Draw(png1)
    font = ImageFont.truetype(r"C:\Windows\Fonts\STFANGSO.ttf", 40, encoding="utf-8")  # 设置字体
    draw.text((190, 300), str1, font=font, fill='black')  # 添加文字
    img_name = str1 + '.jpg'  # 海报名称

    QR_name = 'code.jpg'  # 二维码名称
    QR_code = qrcode.make(str1)  # 生成二维码
    QR_code.save(QR_name)  # 保存二维码

    png_QR = Image.open(QR_name)  # 重新打开二维码图片
    png_QR.thumbnail((80, 80), Image.ANTIALIAS)  # 改变二维码大小
    png_QR.save(QR_name)  # 保存修改尺寸后的二维码

    png_QR = Image.open(QR_name)  # 重新打开二维码图片
    png1.paste(png_QR, (35, 595))  # 添加到海报上
    png1.save(img_name)  # 保存海报

    os.remove(QR_name)  # 删除二维码文件

定义为函数,剩下的就是批量生成了,这是最简单的一步,不赘述了

name_list = ['张三','李四']
for i in name_list:
    poster('model.jpg', i)

最后谈谈自己的收获吧:
第一,先写需求分析,这点最重要,捋清楚思路再下手,事半功倍!

第二,不会没关系,百度一下,都能找到答案,要是找不到答案,可以直接去找相关模块的中文文档,API中会有介绍,不过都写的比较简单,看着有点费劲。
第三,多练,多练,多练!