使用python將任意張圖片拼接成多張大圖

今天看到在之前的一篇博客下有位朋友留言提到了“將多張圖片拼接成多張大圖”的問題,這一系列的博客已經寫了三篇了,這是第四篇了,後三篇全都是基於廣大博友的熱心提問而成型的,十分感謝各位的關注,讓我們一起進步吧~~~

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

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,這就是本篇的全部內容了,還是那句話,歡迎各位的提問,讓我們共同進步~

如果本篇內容對你有一點點幫助,請點個贊或者收藏關注一下,讓我們一起努力

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章