为什么要批量裁剪图片做电商要统一主图尺寸、社交媒体头像要裁成正方形、证件照需要固定比例……手动一张张裁几十张就够你喝两杯咖啡了。用Python Pillow几行代码就能批量搞定。这篇博客覆盖最常用的3个场景每个都给可运行代码。场景一固定尺寸裁剪左上角裁剪最简单粗暴的方式把所有图片裁成统一的宽×高。fromPILimportImageimportosdefcrop_fixed_size(input_dir,output_dir,width,height):os.makedirs(output_dir,exist_okTrue)forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith((.jpg,.jpeg,.png,.bmp,.webp)):continueimg_pathos.path.join(input_dir,filename)imgImage.open(img_path)# 左上角裁剪croppedimg.crop((0,0,width,height))cropped.save(os.path.join(output_dir,filename))print(f{filename}→{width}x{height})# 使用裁成 800x600crop_fixed_size(rD:\原图,rD:\裁剪后,800,600)⚠️ 如果原图比目标尺寸小会报错。下面的居中裁剪可以解决这个问题。场景二居中裁剪成正方形最常用社交媒体头像、商品主图基本都要正方形。这个方法会自动居中裁剪不会拉伸变形。fromPILimportImageimportosdefcrop_center_square(input_dir,output_dir,size):os.makedirs(output_dir,exist_okTrue)forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith((.jpg,.jpeg,.png,.bmp,.webp)):continueimg_pathos.path.join(input_dir,filename)imgImage.open(img_path)# 取最小边作为裁剪尺寸保证不会切掉内容min_sidemin(img.width,img.height)left(img.width-min_side)//2top(img.height-min_side)//2rightleftmin_side bottomtopmin_side croppedimg.crop((left,top,right,bottom))# 再缩放到目标尺寸可选croppedcropped.resize((size,size),Image.LANCZOS)cropped.save(os.path.join(output_dir,filename))print(f{filename}→{size}x{size})# 使用裁成 500x500 正方形crop_center_square(rD:\照片,rD:\头像,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_okTrue)left,top,right,bottomcoords crop_widthright-left crop_heightbottom-topforfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith((.jpg,.jpeg,.png,.bmp,.webp)):continueimg_pathos.path.join(input_dir,filename)imgImage.open(img_path)# 判断原图是否够大ifimg.widthrightorimg.heightbottom:print(f⚠️{filename}尺寸不足跳过)continuecroppedimg.crop((left,top,right,bottom))cropped.save(os.path.join(output_dir,filename))print(f{filename}→ 裁剪区域{coords})# 使用裁剪左上角 (100, 50) 到 (600, 550) 的区域crop_by_coordinates(rD:\截图,rD:\裁剪后,(100,50,600,550))进阶批量裁剪 加水印一气呵成裁剪完直接加上水印电商场景特别实用。fromPILimportImage,ImageDraw,ImageFontimportosdefcrop_and_watermark(input_dir,output_dir,size,watermark_text):os.makedirs(output_dir,exist_okTrue)forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith((.jpg,.jpeg,.png)):continueimg_pathos.path.join(input_dir,filename)imgImage.open(img_path)# 居中裁剪min_sidemin(img.width,img.height)left(img.width-min_side)//2top(img.height-min_side)//2croppedimg.crop((left,top,leftmin_side,topmin_side))croppedcropped.resize((size,size),Image.LANCZOS)# 加水印drawImageDraw.Draw(cropped)fontImageFont.truetype(simhei.ttf,int(size*0.08))# Windows自带黑体text_bboxdraw.textbbox((0,0),watermark_text,fontfont)text_widthtext_bbox[2]-text_bbox[0]x(size-text_width)//2ysize-int(size*0.1)draw.text((x,y),watermark_text,fill(255,255,255,128),fontfont)cropped.save(os.path.join(output_dir,filename),quality95)print(f{filename}→ 裁剪水印完成)# 使用crop_and_watermark(rD:\商品图,rD:\成品,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格式总结批量裁剪图片的核心就三步打开图片→Image.open()裁剪区域→img.crop((左, 上, 右, 下))保存结果→img.save()上面的代码覆盖了固定尺寸、居中正方形、精确坐标三种最常见需求复制过去改一下路径就能跑。如果你需要更复杂的操作比如按人脸自动裁剪、批量加圆角评论区说我接着写。