之前在毕业季的时候,自己手上积攒了一堆照片,然后想一口气发出来祭奠一下自己的大学生涯,于是只好把一堆图片拼接起来。想当然地,用美图秀秀,简单方便还好看,(划重点,此处不是给美图秀秀打软广!!),可是,当手头上想拼接的图片是七八十张起步时,用美图秀秀就不现实了。于是乎,大概是因为我是闲人吧,我尝试着用Python
写了个拼接图片的程序。当然,因为我懒,所以写了有两个月研究生都快开学了才想着整理出来,详细的程序分析此处就省略了哈哈,毕竟呢,“talk is cheap, show me your code!”
# -*- coding:utf-8 -*-
import os
from PIL import Image, ExifTags
import numpy as np
# read image taken by mobile phone, automatically adjust the angle of pictures to the correct location.
def read_img(file):
img = Image.open(file)
try:
for orientation in ExifTags.TAGS.keys() :
if ExifTags.TAGS[orientation] == 'Orientation': break
exif=dict(img._getexif().items())
if exif[orientation] == 3 :
img=img.rotate(180, expand = True)
elif exif[orientation] == 6 :
img=img.rotate(270, expand = True)
elif exif[orientation] == 8 :
img=img.rotate(90, expand = True)
except:
pass
return img
# merge images vertically.
def merge_vertical_numpy(arrays, picture_name):
baseImg = arrays[0]
baseSize = baseImg.size
baseMat = np.array(baseImg) # transform the dimension to 2d
for img in arrays[1:]:
# resize to same width
tmpSize = img.size
if tmpSize != baseSize:
img = img.resize((baseSize[0], round(baseSize[0] / tmpSize[0] * tmpSize[1])), Image.ANTIALIAS)
mat = np.array(img)
baseMat = np.append(baseMat, mat, axis=0)
report_img = Image.fromarray(baseMat)
report_img.save(picture_name)
# merge images horizontally.
def merge_horizontal(files):
baseImg = read_img(files[0])
baseSize = baseImg.size
# for function 'np.array' or 'np.atleast_2d', I think that image quality through 'np.array' is lower than 'np.atleast_2d'.
# method 1:
baseMat = np.array(baseImg)
# method 2:
# basemat = np.atleast_2d(baseImg) # transform the dimension to 2d
for file in files[1:]:
img = read_img(file)
# resize to same width
tmpSize = img.size
if tmpSize != baseSize:
img = img.resize((round(baseSize[1] / tmpSize[1] * tmpSize[0]), baseSize[1]), Image.ANTIALIAS) # Image.ANTIALIAS -- high quality
mat = np.array(img)
baseMat = np.append(baseMat, mat, axis=1)
report_img = Image.fromarray(baseMat)
return report_img
"""params:
dirname: dir which contains pictures waiting to be merged
horizontal_num: nums of pictures horizontally
vertical_num: nums of pictures vertically
picture_name: name of saved picture
"""
def merge(dirname, horizontal_num, vertical_num, picture_name):
files = [file for file in os.listdir(dirname)]
# confirm that horizontal_num * vertical_num == number of total images
if len(files) != horizontal_num * vertical_num:
raise Exception("Invalid horizontal nums or vertical nums!")
files_seg = []
numpy_seg = []
lineCnt = 0
for i in range(len(files)):
files_seg.append('{}/{}'.format(dirname, files[i]))
if (i + 1) % horizontal_num == 0:
numpy_seg.append(merge_horizontal(files_seg))
lineCnt += 1
print('generate image line {}'.format(lineCnt))
files_seg = []
merge_vertical_numpy(numpy_seg, picture_name)
if __name__ == '__main__':
merge('./美好', 10, 10, 'merge_wounderfun.jpg')
最后附一张生成图片吧~