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

资讯详情

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

Python如何分割图片:使用Pillow实现图像等分切割

Python如何分割图片:使用Pillow实现图像等分切割 实际开发中经常需要把一张大图均匀切分成多张小图比如拼图验证码处理、数据集切片、图片九宫格处理。本文基于Python PillowPIL库实现可复用的图片分割函数支持传入Image对象返回切割后的子图对象列表可选择是否落地保存文件。环境准备首先安装Pillow库pipinstallpillow需求说明输入PIL的Image图片对象分割份数NN×N等分输出分割之后的子图Image对象列表不强制写磁盘可选保存到本地文件夹示例场景300×300图片split_count3输出9张100×100的子图。完整代码实现fromPILimportImageimportosfromtypingimportListdefsplit_image(img:Image.Image,split_count:int,save_dir:strNone)-List[Image.Image]: PIL图片N×N等分分割 :param img: 输入PIL Image对象 :param split_count: 分割份数3代表3×3输出9张子图 :param save_dir: 不为None时保存子图到此目录None不落地磁盘 :return: 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)save_pathos.path.join(save_dir,ftile_x{x}_y{y}.png)tile.save(save_path)returntile_listif__name____main__:# 示例用法big_imgImage.open(test.jpg)tilessplit_image(big_img,split_count3)print(f分割得到{len(tiles)}张子图)print(f单张子图尺寸:{tiles[0].size})# 单独保存中间一张图片# tiles[4].save(middle.png)# 如果需要全部保存到本地传入save_dir参数# tiles split_image(big_img, split_count3, save_dir./split_out)核心原理讲解1. Image.crop() 裁剪函数Pillow中crop((left, upper, right, lower))是图片裁剪核心API四个参数分别代表left裁剪区域左边界x坐标upper裁剪区域上边界y坐标right裁剪区域右边界x坐标lower裁剪区域下边界y坐标2. 坐标计算逻辑假设原图宽高为w,h分割份数为split_count每一小块宽度tile_w w // split_count每一小块高度tile_h h // split_count双层循环y为行优先外层循环x为列内层循环。leftx*tile_w uppery*tile_h rightlefttile_w loweruppertile_h3. 返回列表的索引顺序3×3示例index:0 → x0,y0 | index:1 →x1,y0 | index:2 →x2,y0 index:3 → x0,y1 | index:4 →x1,y1 | index:5 →x2,y1 index:6 → x0,y2 | index:7 →x1,y2 | index:8 →x2,y2多种调用示例示例1只做内存分割不保存文件适合深度学习数据集预处理直接拿到子图对象做后续处理。imgImage.open(300x300.jpg)tile_listsplit_image(img,split_count3)# tile_list 里面全部是PIL Image对象可以直接转numpy、做缩放等操作示例2分割同时保存全部子图到文件夹imgImage.open(300x300.jpg)tile_listsplit_image(img,split_count3,save_dir./output)示例3分割后只保存其中某一张imgImage.open(300x300.jpg)tilessplit_image(img,split_count3)tiles[4].save(center.png)⚠️注意事项整除问题当前代码使用整数除法//如果原图宽高不能被split_count整除图片右下角多余像素会直接丢弃。对象生命周期返回的子图是裁剪出来的新Image对象和原图相互独立。本函数只支持N行N列正方形等分如果需要自定义行列比如2行3列可以修改函数增加rows,cols两个入参。扩展配套图片拼接函数很多场景分割之后还需要把子图列表重新合并回大图这里提供配套的合并函数defmerge_images(tile_list:List[Image.Image],split_count:int)-Image.Image: 将N×N分割得到的子图列表重新拼接回原图 :param tile_list: split_image返回的子图列表 :param split_count: 分割时使用的份数 :return: 拼接完成的PIL Image对象 tile_w,tile_htile_list[0].size out_wtile_w*split_count out_htile_h*split_count out_imgImage.new(RGB,(out_w,out_h))idx0foryinrange(split_count):forxinrange(split_count):out_img.paste(tile_list[idx],(x*tile_w,y*tile_h))idx1returnout_img# 使用示例mergedmerge_images(tiles,split_count3)merged.save(merged.jpg)总结函数接收PIL Image对象无需传入文件路径更适合内存中流水线处理。返回子图对象列表灵活选择是否写磁盘适配数据集处理、九宫格、验证码切片等场景。配合merge_images函数实现分割-拼接完整流程。完整源码可直接复制运行可根据业务需求扩展补白逻辑处理不能整除的图片尺寸。
返回列表