图片拼接成长图,无压缩

查看 136|回复 12
作者:Listentomusic   
今天领导让我做一个简单的使用手册,但是找了几个软件都不是很好用于是就用Ai写了一个。
使用方法:
1. 将需要拼接的图片,放进一个文件夹;
2. 图片文件名为整数,程序会按数字顺序自动排序。
[Python] 纯文本查看 复制代码import os
from PIL import Image
def is_valid_image_name(filename):
    """ 检查文件名是否为有效整数 """
    try:
        int(os.path.splitext(filename)[0])
        return True
    except ValueError:
        return False
def stitch_images(folder_path):
    # 获取文件夹中的所有文件,并按文件名排序
    images = sorted([f for f in os.listdir(folder_path) if f.endswith('.jpg') or f.endswith('.png')],
                    key=lambda x: int(os.path.splitext(x)[0]) if is_valid_image_name(x) else float('inf'))
    # 检查是否有非整数文件名
    invalid_files = [f for f in images if not is_valid_image_name(f)]
    if invalid_files:
        print(f"以下文件名非有效:{invalid_files}")
        return
    # 打开所有图像并计算拼接后的总高度和最大宽度
    image_list = [Image.open(os.path.join(folder_path, img)) for img in images]
    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("无效的文件夹路径,请重试。")


Snipaste_2024-10-12_15-07-41.jpg (231.32 KB, 下载次数: 0)
下载附件
2024-10-12 15:07 上传

图片, 文件名

shadmmd   

调整2处避免多图爆内存:
1、用循环读取替代列表推导式,这样就不会一次过读取全部图片到内存。
2、分开两次循环来用with打开文件,避免内存占用在拼接最后一个图片的时候增长到所有图片的2倍。
[Python] 纯文本查看 复制代码def stitch_images(folder_path):
    """
    将指定文件夹中的图片按文件名顺序拼接成长图,并使每张图片水平居中。
    参数:
    :param folder_path: 要拼接图片的文件夹路径
    :return None
    """
    # 获取文件夹中的所有文件,并按文件名排序
    images = sorted([f for f in os.listdir(folder_path) if f.endswith('.jpg') or f.endswith('.png')],
                    key=lambda x: int(os.path.splitext(x)[0]) if is_valid_image_name(x) else float('inf'))
    # 检查是否有非整数文件名
    invalid_files = [f for f in images if not is_valid_image_name(f)]
    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 15:55
后缀不一样能不能拼图,大小不一样

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

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


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

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

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

后缀不一样能不能拼图,大小不一样
你的明媚我的城   

看一看这个
gdfs59310   

竖着的还是横着的?
sapin   

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

返回顶部