尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

如何使用Python Pillow库实现图片的拼接

如何使用Python Pillow库实现图片的拼接 在图像处理任务中图片拼接是非常常见的需求把多张小图拼成一张大图常用于数据集还原、九宫格图片复原、图像切片后重组、拼图业务等。Pillow(PIL)通过Image.new()创建空白画布 paste()粘贴图片实现拼接支持横向拼接、纵向拼接、N×N矩阵拼接。环境准备pipinstallpillow核心API说明Image.new(mode, size)创建空白画布mode图像模式RGB彩色RGBA带透明通道size(width, height)画布宽高canvas.paste(image, (x, y))把图片粘贴到画布的(x,y)坐标位置x粘贴起始横坐标y粘贴起始纵坐标⚠️注意paste不会自动缩放图片粘贴的子图尺寸必须和预留位置大小匹配。场景1横向拼接左右排列把多张图片从左到右拼在一起所有图片高度必须一致。fromPILimportImagefromtypingimportListdefconcat_horizontal(img_list:List[Image.Image])-Image.Image:横向拼接图片从左向右排列要求所有图片高度相同ifnotimg_list:raiseValueError(图片列表不能为空)# 总宽度为所有图片宽度之和高度取第一张图高度total_widthsum(img.widthforimginimg_list)heightimg_list[0].height canvasImage.new(RGB,(total_width,height))offset_x0forimginimg_list:canvas.paste(img,(offset_x,0))offset_ximg.widthreturncanvas# 示例调用if__name____main__:im1Image.open(a.jpg)im2Image.open(b.jpg)im3Image.open(c.jpg)resultconcat_horizontal([im1,im2,im3])result.save(horizontal.jpg)场景2纵向拼接上下排列多张图片从上往下拼接所有图片宽度必须一致。defconcat_vertical(img_list:List[Image.Image])-Image.Image:纵向拼接图片从上向下排列要求所有图片宽度相同ifnotimg_list:raiseValueError(图片列表不能为空)total_heightsum(img.heightforimginimg_list)widthimg_list[0].width canvasImage.new(RGB,(width,total_height))offset_y0forimginimg_list:canvas.paste(img,(0,offset_y))offset_yimg.heightreturncanvas# result concat_vertical([im1, im2, im3])# result.save(vertical.jpg)场景3N×N矩阵拼接和之前分割函数配套针对上一篇博客split_image()分割出来的子图列表行优先还原大图。输入子图列表 矩阵阶数split_count输出完整大图。适用3×3、4×4九宫格复原子图尺寸全部相同。defmerge_image_grid(tile_list:List[Image.Image],split_count:int)-Image.Image: N × N 矩阵拼接与split_image分割函数配套 :param tile_list: split_image返回的子图列表行优先顺序 :param split_count: 分割份数3代表3行3列 :return: 拼接完成的PIL Image对象 ifnottile_list:raiseValueError(子图列表不能为空)iflen(tile_list)!split_count*split_count:raiseValueError(f子图数量不匹配需要{split_count*split_count}张实际{len(tile_list)}张)tile_w,tile_htile_list[0].size canvas_wtile_w*split_count canvas_htile_h*split_count canvasImage.new(RGB,(canvas_w,canvas_h))index0foryinrange(split_count):forxinrange(split_count):canvas.paste(tile_list[index],(x*tile_w,y*tile_h))index1returncanvasif__name____main__:# 和分割代码完整联调示例fromPILimportImagefromyour_moduleimportsplit_image big_imgImage.open(300x300.jpg)tilessplit_image(big_img,split_count3)merged_imgmerge_image_grid(tiles,split_count3)merged_img.save(merge_output.jpg)场景4自定义行列拼接M行N列非正方形如果你想要 2行3列不是N×N正方形矩阵defmerge_custom_grid(tile_list:List[Image.Image],rows:int,cols:int)-Image.Image:自定义行列矩阵拼接 rows行 cols列tile_w,tile_htile_list[0].size canvasImage.new(RGB,(tile_w*cols,tile_h*rows))idx0foryinrange(rows):forxinrange(cols):canvas.paste(tile_list[idx],(x*tile_w,y*tile_h))idx1returncanvas# 示例2行3列共6张图片# out merge_custom_grid(tiles, rows2, cols3)处理透明通道 RGBA如果你的图片是png带透明创建画布时把模式改为RGBAcanvasImage.new(RGBA,(canvas_w,canvas_h))⚠️常见踩坑点子图尺寸不一致paste不会自动缩放子图大小不一样会出现错位、溢出。需要先统一尺寸。图片模式不匹配RGB图片粘贴到RGBA画布可以RGBA粘贴到RGB画布会丢失透明通道建议统一模式。列表顺序错误矩阵拼接严格依赖列表顺序必须和分割时遍历顺序行优先保持一致。索引越界子图数量不等于 rows×cols直接抛出异常避免生成错误图片。完整闭环分割 拼接完整示例fromPILimportImageimportosfromtypingimportListdefsplit_image(img:Image.Image,split_count:int,save_dir:strNone)-List[Image.Image]:w,himg.size tile_ww//split_count tile_hh//split_count tile_list:List[Image.Image][]foryinrange(split_count):forxinrange(split_count):leftx*tile_w uppery*tile_h rightlefttile_w loweruppertile_h tileimg.crop((left,upper,right,lower))tile_list.append(tile)ifsave_dirisnotNone:os.makedirs(save_dir,exist_okTrue)tile.save(os.path.join(save_dir,ftile_x{x}_y{y}.png))returntile_listdefmerge_image_grid(tile_list:List[Image.Image],split_count:int)-Image.Image:ifnottile_list:raiseValueError(子图列表不能为空)iflen(tile_list)!split_count*split_count:raiseValueError(f子图数量不匹配需要{split_count*split_count}张实际{len(tile_list)}张)tile_w,tile_htile_list[0].size canvas_wtile_w*split_count canvas_htile_h*split_count canvasImage.new(RGB,(canvas_w,canvas_h))index0foryinrange(split_count):forxinrange(split_count):canvas.paste(tile_list[index],(x*tile_w,y*tile_h))index1returncanvasif__name____main__:src_imgImage.open(test.jpg)tile_listsplit_image(src_img,split_count3)print(f分割得到{len(tile_list)}张图片)restore_imgmerge_image_grid(tile_list,split_count3)restore_img.save(restore.jpg)print(完成分割复原输出 restore.jpg)总结Image.new()创建空白画布paste()实现图片粘贴是Pillow拼接的底层核心。分为横向、纵向、矩阵N×N三种常用场景矩阵拼接可以完美复原之前分割出来的图片。注意图片尺寸、图像模式、列表顺序这三个是拼接出错最高的地方。分割与拼接组合完成图片切片、复原完整流程适合数据集预处理、九宫格业务。拓展方向可以增加边框、间隙在子图之间添加空白间隔也可以增加缩放逻辑自动适配子图大小。
返回列表