一、程序展示
from PIL import Image
import os
import matplotlib.pyplot as plt
name="Pic"
if not os.path.exists(name):
os.mkdir(name)
files=os.listdir(name)
# lst=[1,2]
# a,b=lst#序列解包,对列表,元组都适用
image_ext=[".jpg",".png",".bmp",".jpeg",".gif"]
images=[]
x = 300#modify the size of images: the value of func-resize
y = 300
# screen out the image
for i in files:
name_pic = os.path.splitext(i)[0]
#is it the picture we want?(识别图片名内是否包含bcm字符串)
if os.path.splitext(i)[-1] in image_ext and "pic" in name_pic:
img = Image.open(name+os.sep+i)
new_img=img.resize((x,y))
images.append(new_img)
heart = [
[0, 0, 1, 0, 0, 0, 1, 0, 0],
[0, 1, 1, 1, 0, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0]
]
col = len(heart[0])
row = len(heart) # int(len(images)/col)
canvas = Image.new("RGBA", (x*col, y*row))
#main program
for k in range(row):
for j in range(col):
if heart[k][j]==1:
idx = j+k*col
canvas.paste(images[idx%len(images)], (j*x, k*y))
# canvas.save("picture.png")#png以RGBA形式
plt.imshow(canvas) # 加载图片
plt.show()
二、讲解
我们用这段代码来生成一个爱心形的拼接图。这段代码一共就分两大部分:1.取出图片文件 2.按照心形创建拼接图。(我使用的图片来自Pic文件夹,大家可以自行创建或使用自己的文件夹,只要里面有图片就行)
1.取出图片
我们想要将Pic文件夹中文件名含有pic的图片文件的筛选出来,用resize()函数将其为300*300像素大小,并添加到images列表中,为以后拼接图片做好准备。取出图片这一步的代码内容和我之前上传的文章“文件备份和文件归档整理程序”几乎一模一样,所以就不再赘述。
2.拼接图片
拼接图片这一步并不难理解。步骤是:选择拼接的形状,再把先前选中的图片拼接上即可。
这里图片形状在列表heart里——我们采用矩阵的思想方法做出一个嵌套列表,其中元素的长是拼接图的宽度,列表长是拼接图长度。元素是1就代表此处插入图片,反之就不插入。
变量canvas是我们用Image.new()方法创建的画布,其中第一个参数是颜色模式,第二个参数是画布大小,单位是像素。
canvas = Image.new("RGBA", (x*col, y*row))
那画布到底要多大呢?我们知道,每张图片都有300x300个像素,而整张拼接图的图片数量=元素长x列表长,也就是9x10=90张图(空白也算)。那整张拼接图换算成像素大小就是2700x3000像素。
> #main program
> for k in range(row):
> for j in range(col):
> if heart[k][j]==1:
> idx = j+k*col
> canvas.paste(images[idx%len(images)], (j*x, k*y))
接下来就是简单的嵌套循环取出列表images中的图片元素并用canvas.paste()将其贴到创建好的画布canvas上。paste()有两个参数,一个是图片,一个是贴的位置。我们能看到 [idx%len(images)] 是一个取余循环,为的就是把取出的图片索引控制在列表长度内。贴的位置讲解之前RLE游程编码中已经详细分析过了,这里就不再重复。