Listentomusic 发表于 2024-10-12 15:11

图片拼接成长图,无压缩

今天领导让我做一个简单的使用手册,但是找了几个软件都不是很好用于是就用Ai写了一个。

使用方法:
1. 将需要拼接的图片,放进一个文件夹;
2. 图片文件名为整数,程序会按数字顺序自动排序。

import os
from PIL import Image


def is_valid_image_name(filename):
    """ 检查文件名是否为有效整数 """
    try:
      int(os.path.splitext(filename))
      return True
    except ValueError:
      return False


def stitch_images(folder_path):
    # 获取文件夹中的所有文件,并按文件名排序
    images = sorted(,
                  key=lambda x: int(os.path.splitext(x)) if is_valid_image_name(x) else float('inf'))

    # 检查是否有非整数文件名
    invalid_files =
    if invalid_files:
      print(f"以下文件名非有效:{invalid_files}")
      return

    # 打开所有图像并计算拼接后的总高度和最大宽度
    image_list =
    max_width = max(img.width for img in image_list)# 取最大宽度
    total_height = sum(img.height for img in image_list)# 所有图片高度总和
    # 创建长图
    stitched_image = Image.new('RGB', (max_width, total_height), color=(255, 255, 255))
    # 将图片逐个粘贴到新图像中,每张图居中显示
    y_offset = 0
    for img in image_list:
      # 计算居中位置
      x_offset = (max_width - img.width) // 2
      stitched_image.paste(img, (x_offset, y_offset))
      y_offset += img.height

    # 保存最终拼接图像
    stitched_image.save(os.path.join(folder_path, 'stitched_image.jpg'), quality=100)
    print(f"拼接完成!保存为:{os.path.join(folder_path, 'stitched_image.jpg')}")


if __name__ == "__main__":
    folder_path = input("请输入图片文件夹路径:")
    if os.path.isdir(folder_path):
      stitch_images(folder_path)
    else:
      print("无效的文件夹路径,请重试。")




shadmmd 发表于 2024-10-13 00:55

调整2处避免多图爆内存:
1、用循环读取替代列表推导式,这样就不会一次过读取全部图片到内存。
2、分开两次循环来用with打开文件,避免内存占用在拼接最后一个图片的时候增长到所有图片的2倍。
def stitch_images(folder_path):
    """
    将指定文件夹中的图片按文件名顺序拼接成长图,并使每张图片水平居中。

    参数:
    :param folder_path: 要拼接图片的文件夹路径
    :return None
    """
    # 获取文件夹中的所有文件,并按文件名排序
    images = sorted(,
                  key=lambda x: int(os.path.splitext(x)) if is_valid_image_name(x) else float('inf'))

    # 检查是否有非整数文件名
    invalid_files =
    if invalid_files:
      print(f"以下文件名非有效:{invalid_files}")
      return

    # 初始化长图的尺寸
    max_width = 0
    total_height = 0

    # 逐个打开图像,计算拼接后的总高度和最大宽度
    for img_name in images:
      img_path = os.path.join(folder_path, img_name)
      with Image.open(img_path) as img:
            max_width = max(max_width, img.width)
            total_height += img.height

    # 创建长图
    stitched_image = Image.new('RGB', (max_width, total_height), color=(255, 255, 255))

    # 逐个粘贴图像到长图上
    y_offset = 0
    for img_name in images:
      img_path = os.path.join(folder_path, img_name)
      with Image.open(img_path) as img:
            # 计算居中位置
            x_offset = (max_width - img.width) // 2
            stitched_image.paste(img, (x_offset, y_offset))
            y_offset += img.height

    # 保存长图
    stitched_image_path = os.path.join(folder_path, 'stitched_image.jpg')
    stitched_image.save(stitched_image_path)

图片更多,那还可以合并两个循环以达到“只对图片文件进行一次读取”的效果。

FeiyuYip 发表于 2024-10-12 16:23

李亲顾 发表于 2024-10-12 15:55
后缀不一样能不能拼图,大小不一样

后缀不一样是可以拼的,反正都PIL是读取之后进行处理,保存时候只能是一种格式了
分辨率不一样也可以,拼接的原理是PIL先新建一个空白的图像,然后将各个小图按设计的位置铺贴上去,对于分辨率更小的图片,要么是边上有留白,或者先对图像进行放大到合适的尺寸再铺贴,就是“满”的了

husay 发表于 2024-10-12 22:24

支持什么图片格式,好不好用,有做好成品的展示吗?

Listentomusic 发表于 2024-10-13 16:44

husay 发表于 2024-10-12 22:24
支持什么图片格式,好不好用,有做好成品的展示吗?

jpg和png,成本的话我环境有问题打包不成exe,只能源码运行了{:1_906:}

supernox 发表于 2024-10-12 15:32

不过有个问题想请教下楼主,如果每个图片的分辨率不一样,或者后缀JPG和PNG,这个咋处理?

李亲顾 发表于 2024-10-12 15:55

后缀不一样能不能拼图,大小不一样

你的明媚我的城 发表于 2024-10-12 16:41

看一看这个

gdfs59310 发表于 2024-10-12 17:05

竖着的还是横着的?

sapin 发表于 2024-10-12 17:06

因为需要自己也写了一个两两合并的代码,为了方便区分背景底图用了显眼(相对)的颜色,而且图片和图片间稍微隔了一点距离,不知是否可以考虑作为改进

Lyaj 发表于 2024-10-12 19:00

试一试效果去

飘水 发表于 2024-10-12 21:42

楼主有成品吗?看看效果

txj66 发表于 2024-10-12 21:50

看看试试效果如何
页: [1] 2 3
查看完整版本: 图片拼接成长图,无压缩