python圖片拼接


python圖片拼接


 

這兩天看到一張圖片,想用python來實現類似的圖片拼接

 

 先分析圖片:

  • 很明顯,這張圖片是由多張圖片疊加拼接而成
  • 從最后一張開始開始疊加,之后的每張圖片都往上平移了一個固定的距離並且附着在原有的圖片上
  • 我們要做的就是控制這個距離,將所有需要的圖片完成這個拼接

實操:

  • 獲取所有需要的圖片的資源
    1 def getAllImg(path):
    2     result = []
    3     filelist = os.listdir(path)
    4     for file in filelist:
    5         if os.path.isfile(os.path.join(path, file)):
    6             if file.split('.')[1] in ('jpg', 'png'):
    7                 result.append(os.path.join(path, file))
    8     return result

     

  • 實現兩張圖片的拼接

     1 result = '/root/lambda/static/result.png'
     2 
     3 
     4 def join(png1, png2, size):
     5     img1, img2 = Image.open(png1), Image.open(png2)
     6     size1, size2 = img1.size, img2.size  # 獲取兩張圖片的大小
     7     joint = Image.new('RGB', (size1[0], size1[1] + size2[1] - size))
     8     # 新建一張新的圖片
     9     # 因為拼接的圖片的寬都是一樣,所以寬為固定值
    10     # 高為兩張圖片的高相加再減去需要縮進的部分
    11     loc1, loc2 = (0, 0), (0, size1[1] - size)
    12     # 兩張圖片的位置
    13     # a-------------
    14     # |            |
    15     # |            |
    16     # |            |
    17     # |            |
    18     # |            |
    19     # b------------|
    20     # |            |
    21     # |            |
    22     # |            |
    23     # |            |
    24     # |--------- --|
    25 
    26     # 位置都是以該圖片的左上角的坐標決定
    27     # 第一張圖片的左上角為a點,a的坐標為(0,0)
    28     # 第二張圖片的左上角為b點,a的橫坐標為0,縱坐標為第一張圖片的縱坐標減去第二張圖片上移的size: (0, size[1]-size)
    29 
    30     joint.paste(img2, loc2)
    31     joint.paste(img1, loc1)
    32     # 因為需要讓第一張圖片放置在圖層的最上面,所以讓第一張圖片最后最后附着上圖片上
    33     joint.save(result)

     

  • 循環遞歸調用

     1 def start(items, size, first_path=None):
     2     # 當first為None時,默認將第一張圖片設置為圖片列表的第一張圖片,第二張圖片設置為圖片列表的第二張
     3     # 當這兩張圖片合成后,將圖片列表的已經合成的圖片元素移除
     4     # 然后將合成的圖片設置為第一張圖片,將剩余的沒有合成的圖片列表繼續操作
     5     # 當first_path不為None,將第一張圖片設置為first_path,第二張圖片設置為傳進來的列表的第一個元素
     6     # 合成之后,將剛剛使用的列表的元素刪除
     7     # 最后遞歸函數,知道列表為空
     8     try:
     9         if not first_path:
    10             path1, path2 = items[0], items[1]
    11             join(path1, path2, size)
    12             items.remove(path1)
    13             items.remove(path2)
    14             return start(items, size, first_path=result)
    15         else:
    16             path2 = items[0]
    17             join(first_path, path2, size)
    18             items.remove(path2)
    19             return start(items, size, first_path=result)
    20     except:
    21         pass
  • 運行

    1 if __name__ == '__main__':
    2     s = getAllImg(path)
    3     s.sort()
    4     start(s, 100)
    5     print('最后圖片尺寸--->', Image.open(result).size)

 

  • 效果展示

  • 圖片文件
  • 1.png
  • 2.png

  • 3.png和1.png是同一張圖片
  • 最終效果圖
  •  

  • 這個中間的間隔是自己把握的,覺得不合適可以任意更換

 

 

  • 完整代碼
  •  1 import os
     2 from PIL import Image
     3 
     4 result = '/root/lambda/static/result.png'  # 圖片保存路徑
     5 
     6 
     7 def join(png1, png2, size):
     8     img1, img2 = Image.open(png1), Image.open(png2)
     9     size1, size2 = img1.size, img2.size  # 獲取兩張圖片的大小
    10     joint = Image.new('RGB', (size1[0], size1[1] + size2[1] - size))
    11     # 新建一張新的圖片
    12     # 因為拼接的圖片的寬都是一樣,所以寬為固定值
    13     # 高為兩張圖片的高相加再減去需要縮進的部分
    14     loc1, loc2 = (0, 0), (0, size1[1] - size)
    15     # 兩張圖片的位置
    16     # a-------------
    17     # |            |
    18     # |            |
    19     # |            |
    20     # |            |
    21     # |            |
    22     # b------------|
    23     # |            |
    24     # |            |
    25     # |            |
    26     # |            |
    27     # |------------|
    28 
    29     # 位置都是以該圖片的左上角的坐標決定
    30     # 第一張圖片的左上角為a點,a的坐標為(0,0)
    31     # 第二張圖片的左上角為b點,a的橫坐標為0,縱坐標為第一張圖片的縱坐標減去第二張圖片上移的size: (0, size[1]-size)
    32 
    33     joint.paste(img2, loc2)
    34     joint.paste(img1, loc1)
    35     # 因為需要讓第一張圖片放置在圖層的最上面,所以讓第一張圖片最后最后附着上圖片上
    36     joint.save(result)
    37 
    38 
    39 def start(items, size, first_path=None):
    40     # 當first為None時,默認將第一張圖片設置為圖片列表的第一張圖片,第二張圖片設置為圖片列表的第二張
    41     # 當這兩張圖片合成后,將圖片列表的已經合成的圖片元素移除
    42     # 然后將合成的圖片設置為第一張圖片,將剩余的沒有合成的圖片列表繼續操作
    43     # 當first_path不為None,將第一張圖片設置為first_path,第二張圖片設置為傳進來的列表的第一個元素
    44     # 合成之后,將剛剛使用的列表的元素刪除
    45     # 最后遞歸函數,知道列表為空
    46     try:
    47         if not first_path:
    48             path1, path2 = items[0], items[1]
    49             join(path1, path2, size)
    50             items.remove(path1)
    51             items.remove(path2)
    52             return start(items, size, first_path=result)
    53         else:
    54             path2 = items[0]
    55             join(first_path, path2, size)
    56             items.remove(path2)
    57             return start(items, size, first_path=result)
    58     except:
    59         pass
    60 
    61 
    62 path = '/root/lambda/'  # 圖片文件夾路徑
    63 
    64 
    65 def getAllImg(path):
    66     result = []
    67     filelist = os.listdir(path)
    68     for file in filelist:
    69         if os.path.isfile(os.path.join(path, file)):
    70             if file.split('.')[1] in ('jpg', 'png'):
    71                 result.append(os.path.join(path, file))
    72     return result
    73 
    74 
    75 if __name__ == '__main__':
    76     s = getAllImg(path)
    77     s.sort()
    78     start(s, 100)
    79     print('最后圖片尺寸--->', Image.open(result).size)

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM