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)

     

 

转载于:https://www.cnblogs.com/ivy-blogs/p/10837394.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值