• 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)

     

  • 相关阅读:
    http_build_query(array) 中文乱码问题
    蒙层
    git删除本地和线上分支
    小程序Storage记录用户身份
    PHPExcel Allowed memory size of 内存泄漏解决办法
    抽奖帮助类
    linux查询并删除文件
    微信公众号H5,分享朋友,分享朋友圈处理
    mysql备份数据方式
    shell监控文件变化
  • 原文地址:https://www.cnblogs.com/ivy-blogs/p/10837394.html
Copyright © 2020-2023  润新知