因为疫情需要经常提供行程码、健康码和核酸码,更麻烦的是需要把三张图拼接成一张长图,用PS(我就只会用PS)过于麻烦,为了方便就做了一个自动拼接图片的脚本,顺便提升一下自己对于Pillow的学习。

功能目标:把选定目标文件夹下的所有图片转化为预定格式(图片模式与其宽高),并最终以对应文件夹的名称输出新图片到指定位置。

pillow内没有直接拼合图片,就只能参考网上其他人的思路,先生成新图片(I)
因为是新手,所以代码过于冗余,等有空再简化修改吧

from PIL import Image
import os

#获取文件夹下所有文件名
imageflie_list = os.listdir(r"文件夹路径")
print(imageflie_list)
#遍历各个图片,并统计图片个数,为新图片size(尺寸)确定作准备
count = 0
for imagefliename in imageflie_list:
    count = count + 1
    imagename = os.path.splitext(imagefliename) #分割获取图片名称与其后缀名,splitext返回一个元组
    image = Image.open("文件夹路径"+"\\"+imagename[0]+imagename[1]) #splitext返回一个元组,所以以[0]、[1]分别表示
    image.load()
    size = (1080, 2100)
    print(image.mode)
    image = image.resize(size) #将图片转化为统一尺寸
    image.convert("RGB").save("文件夹路径\\"+imagename[0]+".jpg")# 图片mode统一转为jpg,因为jpg的mode是RBG,png的mode是RBGA

处理图片的库选择了pillow,调用os以方便后面的遍历和获取文件名、文件后缀名操作。

在这一步中有一个小坑是"Image.open()"直接使用会出现“查找已关闭文件的错误”,在其后面加上"image.load()"解决了这个问题。

image = Image.open("文件夹路径"+"\\"+imagename[0]+imagename[1])
    image.load()

之后是根据前面的遍历结果进行计数,统计有多少张图片,以此确定新图片的高(图片数*单张图片高),生成新图片,再将旧图片一一粘贴到新图片上,由此达到图片拼接的效果。

#输出计数结果并生成对应size图片
countend = int(count)
print(countend)
size = (1080, 2100)
new_image = Image.new('RGB', (size[0], countend * size[1]))

#遍历粘贴,生成新图片
new_count = 0
for imagefliename1 in imageflie_list:
    imageendname = os.path.splitext(imagefliename1)
    end_image = Image.open("文件夹路径"+"\\"+imageendname[0]+imageendname[1])
    new_image.paste(end_image, (0, new_count * size[1])) #new_count * size[1]用于改变每张图片的粘贴位置,例如第一张图片粘贴在0,0,第二张图片就粘贴在0,2100,以此形成图片拼接的效果。
    new_image.save(r"文件夹路径\new.jpg", "JPEG")
    new_count = new_count + 1

写到最后时遇到一个问题,就是新生成图片粘贴无效,不论怎么粘贴都是黑的,其他的都正常。折磨了两个小时后,终于发现了原因:
原先的代码是:

new_image.paste =(end_image, (0, new_count * size[1]))

而正确的代码是:

new_image.paste(end_image, (0, new_count * size[1]))

失之毫厘谬以千里,以后遇到bug时一定要多多仔细看看自己的代码有没有出错。

最后附上完整的代码:

from PIL import Image
import os

#获取文件夹下所有文件名
imageflie_list = os.listdir(r"文件夹路径")
print(imageflie_list)
#遍历各个图片,并统计图片个数,为新图片size(尺寸)确定作准备
count = 0
for imagefliename in imageflie_list:
    count = count + 1
    imagename = os.path.splitext(imagefliename) #分割获取图片名称与其后缀名,splitext返回一个元组
    image = Image.open("文件夹路径"+"\\"+imagename[0]+imagename[1]) #splitext返回一个元组,所以以[0]、[1]分别表示
    image.load()
    size = (1080, 2100)
    print(image.mode)
    image = image.resize(size) #将图片转化为统一尺寸
    image.convert("RGB").save("文件夹路径\\"+imagename[0]+".jpg")# 图片mode统一转为jpg,因为jpg的mode是RBG,png的mode是RBGA
    #输出计数结果并生成对应size图片
countend = int(count)
print(countend)
size = (1080, 2100)
new_image = Image.new('RGB', (size[0], countend * size[1]))

#遍历粘贴,生成新图片
new_count = 0
for imagefliename1 in imageflie_list:
    imageendname = os.path.splitext(imagefliename1)
    end_image = Image.open("文件夹路径"+"\\"+imageendname[0]+imageendname[1])
    new_image.paste(end_image, (0, new_count * size[1])) #new_count * size[1]用于改变每张图片的粘贴位置,例如第一张图片粘贴在0,0,第二张图片就粘贴在0,2100,以此形成图片拼接的效果。
    new_image.save(r"文件夹路径\new.jpg", "JPEG")
    new_count = new_count + 1