当前位置: 首页 > news >正文

如何使用Python批量裁剪图片?3种场景,代码直接拿去用

为什么要批量裁剪图片?

做电商要统一主图尺寸、社交媒体头像要裁成正方形、证件照需要固定比例……手动一张张裁,几十张就够你喝两杯咖啡了。

用Python + Pillow,几行代码就能批量搞定。这篇博客覆盖最常用的3个场景,每个都给可运行代码。


场景一:固定尺寸裁剪(左上角裁剪)

最简单粗暴的方式:把所有图片裁成统一的宽×高。

fromPILimportImageimportosdefcrop_fixed_size(input_dir,output_dir,width,height):os.makedirs(output_dir,exist_ok=True)forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith(('.jpg','.jpeg','.png','.bmp','.webp')):continueimg_path=os.path.join(input_dir,filename)img=Image.open(img_path)# 左上角裁剪cropped=img.crop((0,0,width,height))cropped.save(os.path.join(output_dir,filename))print(f"{filename}{width}x{height}")# 使用:裁成 800x600crop_fixed_size(r'D:\原图',r'D:\裁剪后',800,600)

⚠️ 如果原图比目标尺寸小,会报错。下面的"居中裁剪"可以解决这个问题。


场景二:居中裁剪成正方形(最常用)

社交媒体头像、商品主图,基本都要正方形。这个方法会自动居中裁剪,不会拉伸变形。

fromPILimportImageimportosdefcrop_center_square(input_dir,output_dir,size):os.makedirs(output_dir,exist_ok=True)forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith(('.jpg','.jpeg','.png','.bmp','.webp')):continueimg_path=os.path.join(input_dir,filename)img=Image.open(img_path)# 取最小边作为裁剪尺寸,保证不会切掉内容min_side=min(img.width,img.height)left=(img.width-min_side)//2top=(img.height-min_side)//2right=left+min_side bottom=top+min_side cropped=img.crop((left,top,right,bottom))# 再缩放到目标尺寸(可选)cropped=cropped.resize((size,size),Image.LANCZOS)cropped.save(os.path.join(output_dir,filename))print(f"{filename}{size}x{size}")# 使用:裁成 500x500 正方形crop_center_square(r'D:\照片',r'D:\头像',500)

效果对比

原图居中裁剪左上角裁剪
1200×800 横图✅ 保留中间主体❌ 只保留左上角
800×1200 竖图✅ 保留中间主体❌ 只保留左上角

场景三:按坐标批量裁剪(精确控制)

有些场景需要精确裁剪某个区域,比如证件照只取头部、截图只取特定区域。

fromPILimportImageimportosdefcrop_by_coordinates(input_dir,output_dir,coords):""" coords: (left, top, right, bottom) 例如:(100, 50, 400, 400) 表示从(100,50)到(400,400)的矩形区域 """os.makedirs(output_dir,exist_ok=True)left,top,right,bottom=coords crop_width=right-left crop_height=bottom-topforfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith(('.jpg','.jpeg','.png','.bmp','.webp')):continueimg_path=os.path.join(input_dir,filename)img=Image.open(img_path)# 判断原图是否够大ifimg.width<rightorimg.height<bottom:print(f"⚠️{filename}尺寸不足,跳过")continuecropped=img.crop((left,top,right,bottom))cropped.save(os.path.join(output_dir,filename))print(f"{filename}→ 裁剪区域{coords}")# 使用:裁剪左上角 (100, 50) 到 (600, 550) 的区域crop_by_coordinates(r'D:\截图',r'D:\裁剪后',(100,50,600,550))

进阶:批量裁剪 + 加水印(一气呵成)

裁剪完直接加上水印,电商场景特别实用。

fromPILimportImage,ImageDraw,ImageFontimportosdefcrop_and_watermark(input_dir,output_dir,size,watermark_text):os.makedirs(output_dir,exist_ok=True)forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith(('.jpg','.jpeg','.png')):continueimg_path=os.path.join(input_dir,filename)img=Image.open(img_path)# 居中裁剪min_side=min(img.width,img.height)left=(img.width-min_side)//2top=(img.height-min_side)//2cropped=img.crop((left,top,left+min_side,top+min_side))cropped=cropped.resize((size,size),Image.LANCZOS)# 加水印draw=ImageDraw.Draw(cropped)font=ImageFont.truetype("simhei.ttf",int(size*0.08))# Windows自带黑体text_bbox=draw.textbbox((0,0),watermark_text,font=font)text_width=text_bbox[2]-text_bbox[0]x=(size-text_width)//2y=size-int(size*0.1)draw.text((x,y),watermark_text,fill=(255,255,255,128),font=font)cropped.save(os.path.join(output_dir,filename),quality=95)print(f"{filename}→ 裁剪+水印完成")# 使用crop_and_watermark(r'D:\商品图',r'D:\成品',800,'店铺名称')

💡 如果是Mac/Linux,字体路径改成/System/Library/Fonts/Supplemental/Arial Unicode.ttf或安装中文字体。


常见问题速查

问题解决方案
图片有透明通道,保存后变黑底cropped.convert('RGB')转成RGB再保存
裁剪后图片模糊resize()Image.LANCZOS而不是默认的Image.BILINEAR
批量处理速度慢考虑用concurrent.futures.ThreadPoolExecutor多线程处理
需要保留EXIF信息piexif库,或pillow-heif处理HEIC格式

总结

批量裁剪图片的核心就三步:

  1. 打开图片Image.open()
  2. 裁剪区域img.crop((左, 上, 右, 下))
  3. 保存结果img.save()

上面的代码覆盖了固定尺寸、居中正方形、精确坐标三种最常见需求,复制过去改一下路径就能跑。

如果你需要更复杂的操作(比如按人脸自动裁剪、批量加圆角),评论区说,我接着写。

http://www.jsqmd.com/news/1052890/

相关文章:

  • 基于深度学习YOLOv8的药物识别检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)
  • 在线最大独立集算法:随机化与几何表示如何解决动态资源分配难题
  • GLM-4.7免费API接入NVIDIA Build平台实操指南
  • Ruby数据类型实战指南:Integers、Floats与Booleans避坑解析
  • 解锁AMD Ryzen隐藏性能:SMUDebugTool让你的处理器发挥真正实力
  • 移动端GUI自动化框架SkillDroid:从技能编译到鲁棒重放
  • 告别网盘限速:9大平台直链下载助手的终极指南
  • 2026泰州漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • 嵌入式GUI多语言支持:emWin资源文件、编码与复杂文字处理实战
  • 终极解决方案:3分钟搞定Windows VC运行库全合一安装,彻底告别DLL缺失烦恼
  • 如何高效使用Pearcleaner:macOS应用清理的终极指南
  • 终极指南:3步快速为Windows 11 LTSC安装微软商店
  • 专家模型特征工程:提升机器学习分类性能与可解释性的实践指南
  • Ubuntu 20.04 + Zabbix 6.0 深度监控 Docker 实战指南
  • 电力系统振荡抑制:基于输出反馈的最小扰动解耦控制原理与实践
  • 如何重构下载体验:开源工具的性能突破指南
  • iOS RSA加密库封装:从Security.framework到安全通信实战
  • 国产大模型本地部署与RAG应用实践指南
  • OpenClaw中文版一键部署指南:Windows本地AI工具链实战解析
  • 泉州莆抖抖可以信任吗 十大实力测评零套路不踩坑 - myqiye
  • emWin核心控件实战:IMAGE、KNOB、LISTBOX开发与避坑指南
  • 176、计算摄影全景:从传统 ISP 到 AI ISP 的技术演进路线图
  • 嵌入式G.729AB语音编解码库集成实战:从API解析到工程避坑
  • 自回归模型实战指南:从原理到零售销量预测落地
  • 星系尘埃分布与巴尔末减光效应研究
  • 3个技巧让网盘下载效率翻倍:开源直链助手完整指南
  • HMCL终极指南:三步轻松搞定Minecraft模组安装与管理
  • 三模聚合平台实战指南:GPT/Claude/Gemini协同工作流
  • 如何通过Ping判断网络是否拥堵?
  • 从56F807到56F8300:嵌入式DSP项目迁移实战与核心差异解析