小言_互联网的博客

使用python将任意张图片拼接成多张大图

433人阅读  评论(0)

今天看到在之前的一篇博客下有位朋友留言提到了“将多张图片拼接成多张大图”的问题,这一系列的博客已经写了三篇了,这是第四篇了,后三篇全都是基于广大博友的热心提问而成型的,十分感谢各位的关注,让我们一起进步吧~~~

先放上之前的三篇吧,都是姊妹篇:

1.使用python将多张图片拼接成大图:https://blog.csdn.net/beyond9305/article/details/83413009

2.基于python的多张不同宽高图片拼接成大图:https://blog.csdn.net/beyond9305/article/details/90143367

3.基于python的多张不同宽高图片拼接成大图——行自适应:https://blog.csdn.net/beyond9305/article/details/90712741

今天的标题在前边的基础上再次开辟新的角度,我们之前都是将多张图片拼接成一张大图,而这次则是拼接任意张大图,当然,这个任意张也不是很严谨,还是会有些限制的,如果后续有需要我们再进一步的探讨,大家感兴趣的话可以参考前几篇博客,然后对本篇进行升级,我们这次就做最简单的工作,将一定数量的图片拼接成目标张数的大图~~

既然这个问题是由热心博友提出的,那我们就按照他的需求来设定参数吧:

这里边有几个点:名字顺序、四个一组、拼接后的图片放在一个文件夹下

首先是名字顺序,我在之前的博客中提到过这个问题,python的库函数对下标的识别和我们认识的不太一样(这一点可能会有局限性,欢迎大佬们指正),比如我们对图片进行标注,顺序为1,2,3……,9,10,11,12……,这是我们认为的顺序,但python不会这么想,它是从左边数第一位作为基准开始识别的,比如他会认为11在2前边,这样的话我们标注图片时可以使用基数分类标注,比如,11,12……21,22……31,32等,如上边博友提到的1.1,1.2就更规范了,还是用事实说话吧,先看看我的图片集:

看我们获取图片名字后的输出:

其次是四个一组,本例中我们一共有20张图片,共输出五张大图,其实这一块我想了很久,尤其是今天我这脑子还有点懵,反应迟钝,思考这种问题总是卡壳,最后修修补补算是顺利完工了吧,可能代码不是最简洁的,但这一需求还是可以满足的,关于这一点我们后边再聊~

最后是输出图片放到统一文件夹,这个只需要设置输出路径即可,我们代码里已经标明了,ok,那就上代码吧:

#!/usr/bin/env python 
# -*- coding:utf-8 -*-

import PIL.Image as Image

import os

IMAGES_PATH = 'D:\Mafengwo\photo\五月坦桑的暖风,非洲原野的呼唤\\'  # 图片集地址

IMAGES_FORMAT = ['.jpg', '.JPG']  # 图片格式

IMAGE_SIZE = 256  # 每张小图片的大小

IMAGE_ROW = 2  # 图片间隔,也就是合并成一张图后,一共有几行

IMAGE_COLUMN = 2  # 图片间隔,也就是合并成一张图后,一共有几列

IMAGE_SAVE_PATH = 'E:\photo\\final'  # 图片转换后的地址,即我们的图片输出路径

# 获取图片集地址下的所有图片名称

image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if

               os.path.splitext(name)[1] == item]

# 定义图像拼接函数

def image_compose():

    for i in range(1, int(len(image_names) / (IMAGE_ROW * IMAGE_COLUMN)) + 1):     #循环的次数为目标输出大图的数量

        to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE))  # 创建一个新图

        # 循环遍历,把每张图片按顺序粘贴到对应位置上
        for y in range(1, IMAGE_ROW + 1):

            for x in range(1, IMAGE_COLUMN + 1):

                from_image = Image.open(IMAGES_PATH + image_names[(i-1)*IMAGE_ROW * IMAGE_COLUMN + IMAGE_COLUMN*(y-1)+x-1]).resize(

                    (IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)  #每次顺序找到四张图片然后生成一张2×2的大图

                to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))

        print(to_image.save(IMAGE_SAVE_PATH+str(i)+".jpg"))  # 保存新图

image_compose()  # 调用函数

我是在第一篇博客的基础上改的,由于有好几个月没有看这一块的知识了,感觉很毛躁,有很多种方案却不知该如何落地,反正就是各种改吧,最后的成型如上所示,当时主要卡在了这里:

Image.open(IMAGES_PATH + image_names[(i-1)*IMAGE_ROW * IMAGE_COLUMN + IMAGE_COLUMN*(y-1)+x-1])

现在大家看到的是三层循环,在原来对行列循环的基础上添加了输出多张图片的循环,其实一开始我是搞了四层循环,结果就在这里停顿了很久,第四层循环主要是解决获取不同位置图片的问题,我设置了变量z,取值依次为1,2,……行×列,对应到本例中也就是1,2,3,4;但这里由于循环之间的嵌套并且不能交叉进行就导致了输出了各种奇形怪状的图片,最后我就尝试寻找变量z和xy之间的关系,然后发现前者完全可以由后者表示,并且只是在前篇博客代码基础上添加

(i-1)*IMAGE_ROW * IMAGE_COLUMN

即可,真的是绕了个大弯,最后又回到了最初,人生亦是如此吧……

最后关于保存路径,可以在IMAGE_SAVE_PATH中设置,其中final是我们图片的名称(准确的说应该是部分名称,为了区分不同图片我们还加入了可变的数字“i”,这样更加直观标准)

ok,这就是本篇的全部内容了,还是那句话,欢迎各位的提问,让我们共同进步~

如果本篇内容对你有一点点帮助,请点个赞或者收藏关注一下,让我们一起努力


转载:https://blog.csdn.net/u014483914/article/details/101316860
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场