Python如何将多张图片按自定义网格布局拼接并设置图片间距
PNG图片网格拼接实现方案
优先推荐轻量高效的Pillow实现,其次提供matplotlib实现版本,均支持自定义每行图片数、图片间隔参数,可直接复现7张图每行3张的拼接效果。
方案1:Pillow实现(推荐)
处理速度快,输出文件体积可控,适合大批量图片拼接场景。
- 安装依赖
pip install pillow - 完整实现代码
from PIL import Image import math def merge_pngs_to_grid(image_paths, output_path, cols=3, gap=10, resize_to_uniform=True, bg_color=(255,255,255)): # 读取所有PNG图片 imgs = [Image.open(p) for p in image_paths] # 统一尺寸适配:默认取所有图最大宽高为基准,居中放置避免图片拉伸变形 if resize_to_uniform: target_w = max(img.width for img in imgs) target_h = max(img.height for img in imgs) processed_imgs = [] for img in imgs: if img.size != (target_w, target_h): canvas = Image.new('RGB', (target_w, target_h), bg_color) offset_x = (target_w - img.width) // 2 offset_y = (target_h - img.height) // 2 canvas.paste(img, (offset_x, offset_y)) processed_imgs.append(canvas) else: processed_imgs.append(img) imgs = processed_imgs else: target_w = max(img.width for img in imgs) target_h = max(img.height for img in imgs) # 计算网格参数与总画布尺寸 total_img = len(imgs) rows = math.ceil(total_img / cols) canvas_w = cols * target_w + (cols + 1) * gap canvas_h = rows * target_h + (rows + 1) * gap merged_canvas = Image.new('RGB', (canvas_w, canvas_h), bg_color) # 逐张粘贴图片到对应网格位置 for idx, img in enumerate(imgs): row_idx = idx // cols col_idx = idx % cols pos_x = gap + col_idx * (target_w + gap) pos_y = gap + row_idx * (target_h + gap) merged_canvas.paste(img, (pos_x, pos_y)) # 保存拼接结果 merged_canvas.save(output_path, format='PNG') print(f"拼接完成,文件已保存至: {output_path}") # 调用示例:7张图、每行3张、间隔10像素 if __name__ == "__main__": # 替换为实际的PNG文件路径列表 png_path_list = [f"pic_{i}.png" for i in range(1,8)] merge_pngs_to_grid( image_paths=png_path_list, output_path="merged_result.png", cols=3, gap=10 ) - 可调参数说明
cols:每行显示的图片数量,对应示例场景传入3即可gap:图片之间、图片与画布边缘的空白间隔像素值,一般设置5-20视觉效果较好resize_to_uniform:默认开启,自动将尺寸不一的图片居中放在统一尺寸的背景块上,不会拉伸变形;不需要统一尺寸可设为Falsebg_color:空白区域背景色,默认白色,可传入RGB元组自定义颜色
方案2:matplotlib实现
适合拼接时需要额外添加标题、标注,或需要快速预览效果的场景。
- 安装依赖
pip install matplotlib pillow - 完整实现代码
import matplotlib.pyplot as plt from PIL import Image import math def merge_pngs_with_matplotlib(image_paths, output_path, cols=3, gap=0.05): total_img = len(image_paths) rows = math.ceil(total_img / cols) # 创建子图网格 fig, axes = plt.subplots(rows, cols, figsize=(cols*3, rows*3), dpi=150) # 将坐标轴数组转为一维列表方便遍历 axes = axes.flatten() if total_img > 1 else [axes] for idx, img_path in enumerate(image_paths): img = Image.open(img_path) axes[idx].imshow(img) # 隐藏子图坐标轴 axes[idx].axis('off') # 隐藏最后一行不足数量的多余空白子图 for idx in range(total_img, len(axes)): axes[idx].axis('off') # 调整子图间距,去除多余白边 plt.subplots_adjust(wspace=gap, hspace=gap, left=0, right=1, top=1, bottom=0) plt.savefig(output_path, format='PNG', bbox_inches='tight', pad_inches=0) plt.close() print(f"拼接完成,文件已保存至: {output_path}") # 调用示例 if __name__ == "__main__": png_path_list = [f"pic_{i}.png" for i in range(1,8)] merge_pngs_with_matplotlib( image_paths=png_path_list, output_path="merged_matplotlib_result.png", cols=3, gap=0.05 )
两种方案均不需要手动排版,修改对应参数即可适配不同的行数、间隔、背景色需求,输出为无损PNG格式。
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

