Python案例如何用Pillow拼接多张图片

wen python案例 3

本文目录导读:

Python案例如何用Pillow拼接多张图片

  1. 水平拼接(横向拼接)
  2. 垂直拼接(纵向拼接)
  3. 网格拼接(矩阵排列)
  4. 自动拼接(包含调整大小)
  5. 批量文件夹图片拼接
  6. 带标题的拼接
  7. 使用建议

我来介绍几种使用Pillow拼接图片的方法:

水平拼接(横向拼接)

from PIL import Image
import os
def horizontal_concat(images_path, output_path="result_horizontal.jpg"):
    """水平拼接多张图片"""
    images = []
    # 读取所有图片
    for path in images_path:
        img = Image.open(path)
        images.append(img)
    # 计算总宽度和最大高度
    total_width = sum(img.width for img in images)
    max_height = max(img.height for img in images)
    # 创建新画布
    new_image = Image.new('RGB', (total_width, max_height), (255, 255, 255))
    # 粘贴图片
    x_offset = 0
    for img in images:
        new_image.paste(img, (x_offset, 0))
        x_offset += img.width
    new_image.save(output_path)
    return new_image
# 使用示例
images = ["image1.jpg", "image2.jpg", "image3.jpg"]
horizontal_concat(images)

垂直拼接(纵向拼接)

def vertical_concat(images_path, output_path="result_vertical.jpg"):
    """垂直拼接多张图片"""
    images = []
    for path in images_path:
        img = Image.open(path)
        images.append(img)
    # 计算最大宽度和总高度
    max_width = max(img.width for img in images)
    total_height = sum(img.height for img in images)
    # 创建新画布
    new_image = Image.new('RGB', (max_width, total_height), (255, 255, 255))
    # 粘贴图片
    y_offset = 0
    for img in images:
        # 水平居中
        x_offset = (max_width - img.width) // 2
        new_image.paste(img, (x_offset, y_offset))
        y_offset += img.height
    new_image.save(output_path)
    return new_image
# 使用示例
images = ["image1.jpg", "image2.jpg", "image3.jpg"]
vertical_concat(images)

网格拼接(矩阵排列)

def grid_concat(images_path, cols=3, output_path="result_grid.jpg"):
    """网格拼接多张图片"""
    images = [Image.open(path) for path in images_path]
    # 获取图片尺寸(取最大尺寸)
    widths = [img.width for img in images]
    heights = [img.height for img in images]
    # 计算每个单元格的尺寸
    cell_width = max(widths)
    cell_height = max(heights)
    # 计算行数
    rows = (len(images) + cols - 1) // cols
    # 创建新画布
    new_image = Image.new('RGB', 
                         (cell_width * cols, cell_height * rows), 
                         (255, 255, 255))
    # 粘贴图片
    for i, img in enumerate(images):
        row = i // cols
        col = i % cols
        # 计算位置
        x = col * cell_width + (cell_width - img.width) // 2
        y = row * cell_height + (cell_height - img.height) // 2
        new_image.paste(img, (x, y))
    new_image.save(output_path)
    return new_image
# 使用示例
images = ["image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg"]
grid_concat(images, cols=2)  # 2列网格

自动拼接(包含调整大小)

def auto_concat(images_path, direction='horizontal', 
                resize=None, padding=10, output_path="result.jpg"):
    """
    自动拼接图片,可选择调整大小和添加间距
    参数:
    - direction: 'horizontal' 或 'vertical'
    - resize: 统一尺寸,如 (300, 200)
    - padding: 图片间距
    """
    images = []
    for path in images_path:
        img = Image.open(path)
        # 调整大小
        if resize:
            img = img.resize(resize, Image.Resampling.LANCZOS)
        images.append(img)
    if direction == 'horizontal':
        # 水平拼接
        total_width = sum(img.width for img in images) + padding * (len(images) - 1)
        max_height = max(img.height for img in images)
        new_image = Image.new('RGB', (total_width, max_height), (255, 255, 255))
        x_offset = 0
        for img in images:
            y_offset = (max_height - img.height) // 2
            new_image.paste(img, (x_offset, y_offset))
            x_offset += img.width + padding
    else:
        # 垂直拼接
        max_width = max(img.width for img in images)
        total_height = sum(img.height for img in images) + padding * (len(images) - 1)
        new_image = Image.new('RGB', (max_width, total_height), (255, 255, 255))
        y_offset = 0
        for img in images:
            x_offset = (max_width - img.width) // 2
            new_image.paste(img, (x_offset, y_offset))
            y_offset += img.height + padding
    new_image.save(output_path)
    return new_image
# 使用示例
auto_concat(["img1.jpg", "img2.jpg"], 
            direction='horizontal', 
            resize=(400, 300), 
            padding=20)

批量文件夹图片拼接

def batch_concat_from_folder(folder_path, output_path="batch_result.jpg"):
    """从文件夹读取图片并拼接"""
    # 获取所有图片文件
    image_extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']
    images_path = []
    for file in os.listdir(folder_path):
        ext = os.path.splitext(file)[1].lower()
        if ext in image_extensions:
            images_path.append(os.path.join(folder_path, file))
    # 按文件名排序
    images_path.sort()
    if not images_path:
        print("未找到图片文件")
        return None
    # 拼接
    return grid_concat(images_path, cols=3, output_path=output_path)
# 使用示例
batch_concat_from_folder("./images_folder")

的拼接

from PIL import Image, ImageDraw, ImageFont
def concat_with_titles(images_path, titles, output_path="titled_concat.jpg"):
    """带标题的图片拼接"""
    # 读取并调整图片
    images = []
    for path in images_path:
        img = Image.open(path)
        img = img.resize((300, 200))
        images.append(img)
    # 创建标题图片height = 40images = []
    for title in titles:
        title_img = Image.new('RGB', (300, title_height), (240, 240, 240))
        draw = ImageDraw.Draw(title_img)
        # 尝试使用中文字体,如果失败则使用默认字体
        try:
            font = ImageFont.truetype("simhei.ttf", 20)
        except:
            font = ImageFont.load_default()
        # 居中显示文字
        bbox = draw.textbbox((0, 0), title, font=font)
        text_width = bbox[2] - bbox[0]
        text_height = bbox[3] - bbox[1]
        x = (300 - text_width) // 2
        y = (title_height - text_height) // 2
        draw.text((x, y), title, fill='black', font=font)
        title_images.append(title_img)
    # 垂直拼接(每个图片带标题)
    final_height = sum(img.height + title_img.height 
                      for img, title_img in zip(images, title_images))
    max_width = max(img.width for img in images)
    new_image = Image.new('RGB', (max_width, final_height), (255, 255, 255))
    y_offset = 0
    for img, title_img in zip(images, title_images):
        new_image.paste(title_img, (0, y_offset))
        y_offset += title_img.height
        x_offset = (max_width - img.width) // 2
        new_image.paste(img, (x_offset, y_offset))
        y_offset += img.height
    new_image.save(output_path)
    return new_image
# 使用示例
images = ["img1.jpg", "img2.jpg", "img3.jpg"]s = ["图片1", "图片2", "图片3"]
concat_with_titles(images, titles)

使用建议

  1. 图片格式:建议统一使用同一种格式(如JPG或PNG)
  2. 尺寸处理:如果图片尺寸差异大,建议先调整大小
  3. 内存管理:大量图片时注意释放内存
  4. 错误处理:添加try-except处理图片读取错误

这些方法可以满足大部分图片拼接需求,根据具体情况选择合适的方法。

抱歉,评论功能暂时关闭!