工作 / 编程 · 2024 年 12 月 16 日 0

用python快速拼接图片

起因

工作需要某一个后台有时候需要传一些图片做为辅助说明,但是传图的地方只可以放一张图,而我经常需要传2~4张图,只能自己拼一拼再上传。
现在的图片在线编辑网站功能太多,设置要选很多内容,我只需要最简单的把几张图片拼在一起,打开之后能看清内容即可,不需要花里胡哨的功能。本来习惯用美图秀秀在线版直接拼接图片,但是最近开始需要登陆账号才能用。只好自己写一个。

整理需求

1.为了能看得清图片,我需要对所有图片进行等比例缩放,以保证不会出现个别图片和其他图片差距太大,拼接后看不清某张图片的情况

2.给图片添加白色底色,这样可以在拼接大小不同的图片时候保证最终输出的图片画面不突兀,没有黑边。输出的时候同时输出横版和竖版,供我挑选。

3.添加根据文件名排序的功能,以便在需要按顺序拼图的时候顺利完成。

最终代码

import os
from PIL import Image

def resize_image(image, target_width, target_height):
    # 等比例调整图像大小
    original_width, original_height = image.size
    aspect_ratio = original_width / original_height
    target_aspect_ratio = target_width / target_height

    if aspect_ratio > target_aspect_ratio:
        # 如果原始图像的宽高比大于目标宽高比,调整宽度
        new_width = target_width
        new_height = int(target_width / aspect_ratio)
    else:
        # 否则,调整高度
        new_height = target_height
        new_width = int(target_height * aspect_ratio)

    return image.resize((new_width, new_height), Image.LANCZOS)  # 使用Lanczos算法

def vertical_concatenate_images(image_list):
    # 纵向拼接图像
    total_height = sum(img.height for img in image_list)
    result_image = Image.new("RGB", (image_list[0].width, total_height), color="white")  # 将背景颜色设置为白色
    y_offset = 0
    for img in image_list:
        result_image.paste(img, (0, y_offset))
        y_offset += img.height
    return result_image

def horizontal_concatenate_images(image_list):
    # 横向拼接图像
    total_width = sum(img.width for img in image_list)
    result_image = Image.new("RGB", (total_width, image_list[0].height), color="white")  # 将背景颜色设置为白色
    x_offset = 0
    for img in image_list:
        result_image.paste(img, (x_offset, 0))
        x_offset += img.width
    return result_image

def main():
    image_folder = "."  # 当前文件夹
    output_filename_vertical = "output_vertical.jpg"  # 纵向拼接输出文件名
    output_filename_horizontal = "output_horizontal.jpg"  # 横向拼接输出文件名

    image_files = [f for f in os.listdir(image_folder) if f.lower().endswith((".png", ".jpg"))]
    image_files.sort()  # 按文件名排序

    images = []
    reference_image_path = os.path.join(image_folder, image_files[0])
    reference_image = Image.open(reference_image_path)
    target_width, target_height = reference_image.size  # 使用第一张图像的尺寸作为目标尺寸

    for i, filename in enumerate(image_files[:10]):
        image_path = os.path.join(image_folder, filename)
        img = Image.open(image_path)
        img = resize_image(img, target_width, target_height)  # 调整大小为目标宽度和高度
        images.append(img)

    result_image_vertical = vertical_concatenate_images(images)
    result_image_vertical.save(output_filename_vertical)
    print(f"图像已纵向拼接并保存为{output_filename_vertical}")

    # 横向拼接部分
    result_image_horizontal = horizontal_concatenate_images(images)
    result_image_horizontal.save(output_filename_horizontal)
    print(f"图像已横向拼接并保存为{output_filename_horizontal}")

if __name__ == "__main__":
    main()

结果

比如我现在有像这样3张尺寸不同的图片

当我运行代码之后,就自动生成横拼和竖拼两张图片,由于横屏留白的面积太大,不太美观,我们就可以挑选竖拼的图片作为最终结果使用。