title: “影刀RPA 图片批量压缩与格式转换:处理大量素材”
date: 2026-07-01
author: 林焱
影刀RPA 图片批量压缩与格式转换:处理大量素材
电商运营有几百张产品图,需要统一压缩到500KB以内、统一转成JPEG、统一加水印、统一改尺寸……这类批量处理任务用影刀+Pillow分分钟搞定,效果比PS批处理更灵活。
什么情况用什么
适合批量处理的场景:
- 电商主图/详情图统一规格(尺寸、格式、大小)
- 新闻稿图片批量压缩后发邮件
- 用户上传图片自动压缩节省存储
- 素材图片统一加品牌水印
不适合的场景:
- 需要专业修图(色彩矫正、抠图),还是用PS
- 只有几张图,手动处理更快
怎么做
准备工作:安装依赖
【影刀操作】
- 添加【Python】指令
importsubprocess subprocess.run(['pip','install','Pillow'],capture_output=True)print('Pillow安装完成')
方法1:批量压缩图片到指定大小
【影刀操作】
- 添加【Python】指令
fromPILimportImageimportosdefcompress_image(input_path,output_path,target_size_kb=500,min_quality=30):""" 压缩图片到指定大小(KB) target_size_kb: 目标大小(KB) min_quality: 最低质量(避免压缩过度) """img=Image.open(input_path)# 如果是PNG或其他格式,转为RGB(JPEG不支持透明通道)ifimg.modein('RGBA','P','LA'):# 透明背景换成白色background=Image.new('RGB',img.size,(255,255,255))ifimg.mode=='RGBA':background.paste(img,mask=img.split()[3])else:background.paste(img)img=backgroundelifimg.mode!='RGB':img=img.convert('RGB')# 检查原始大小original_size=os.path.getsize(input_path)/1024iforiginal_size<=target_size_kb:# 已经够小,只做格式转换img.save(output_path,'JPEG',quality=85,optimize=True)print(f'无需压缩:{os.path.basename(input_path)}({original_size:.0f}KB)')return# 二分法找到合适的quality值quality_low,quality_high=min_quality,95best_output=Nonewhilequality_low<=quality_high:quality=(quality_low+quality_high)//2importiobuffer=io.BytesIO()img.save(buffer,'JPEG',quality=quality,optimize=True)size_kb=buffer.tell()/1024ifsize_kb<=target_size_kb:best_output=buffer.getvalue()quality_low=quality+1# 尝试更高质量else:quality_high=quality-1# 继续压缩ifbest_output:withopen(output_path,'wb')asf:f.write(best_output)final_size=os.path.getsize(output_path)/1024print(f'压缩完成:{os.path.basename(input_path)}{original_size:.0f}KB →{final_size:.0f}KB')else:# 质量已经降到最低,直接保存img.save(output_path,'JPEG',quality=min_quality,optimize=True)print(f'压缩至最低质量:{os.path.basename(input_path)}')# 批量处理input_dir=r'C:\原始图片'output_dir=r'C:\压缩图片'os.makedirs(output_dir,exist_ok=True)image_exts={'.jpg','.jpeg','.png','.bmp','.tiff','.webp'}processed=0forfilenameinos.listdir(input_dir):ext=os.path.splitext(filename)[1].lower()ifextnotinimage_exts:continueinput_path=os.path.join(input_dir,filename)# 输出统一用jpg后缀output_name=os.path.splitext(filename)[0]+'.jpg'output_path=os.path.join(output_dir,output_name)compress_image(input_path,output_path,target_size_kb=500)processed+=1print(f'\n处理完成:共处理{processed}张图片')yda.set_variable('processed_count',processed)
方法2:批量调整图片尺寸
【影刀操作】
- 添加【Python】指令
fromPILimportImageimportosdefresize_image(input_path,output_path,target_width=800,target_height=None,mode='fit',fill_color=(255,255,255)):""" mode: 'fit' - 等比缩放,放在目标尺寸内(不裁剪,可能有留白) 'fill' - 裁剪到精确尺寸 'stretch' - 强制拉伸到目标尺寸 """img=Image.open(input_path)orig_w,orig_h=img.sizeiftarget_heightisNone:# 只指定宽度,等比缩放ratio=target_width/orig_w target_height=int(orig_h*ratio)ifmode=='fit':img.thumbnail((target_width,target_height),Image.LANCZOS)# 居中放置,周围填充背景色background=Image.new('RGB',(target_width,target_height),fill_color)offset=((target_width-img.width)//2,(target_height-img.height)//2)background.paste(img,offset)result=backgroundelifmode=='fill':# 先缩放到覆盖目标尺寸,再中心裁剪ratio=max(target_width/orig_w,target_height/orig_h)new_w=int(orig_w*ratio)new_h=int(orig_h*ratio)img=img.resize((new_w,new_h),Image.LANCZOS)# 中心裁剪left=(new_w-target_width)//2top=(new_h-target_height)//2result=img.crop((left,top,left+target_width,top+target_height))else:# stretchresult=img.resize((target_width,target_height),Image.LANCZOS)ifresult.mode!='RGB':result=result.convert('RGB')result.save(output_path,'JPEG',quality=90,optimize=True)# 批量处理(电商主图统一800x800)input_dir=r'C:\商品图片\原图'output_dir=r'C:\商品图片\800x800'os.makedirs(output_dir,exist_ok=True)forfilenameinos.listdir(input_dir):iffilename.lower().endswith(('.jpg','.jpeg','.png')):input_path=os.path.join(input_dir,filename)output_path=os.path.join(output_dir,os.path.splitext(filename)[0]+'.jpg')resize_image(input_path,output_path,800,800,mode='fill')print(f'处理:{filename}')
方法3:批量格式转换
【影刀操作】
fromPILimportImageimportosdefconvert_format(input_dir,output_dir,from_format='png',to_format='jpg',quality=90):"""批量转换格式"""os.makedirs(output_dir,exist_ok=True)count=0forfilenameinos.listdir(input_dir):ifnotfilename.lower().endswith('.'+from_format):continueinput_path=os.path.join(input_dir,filename)output_filename=os.path.splitext(filename)[0]+'.'+to_format output_path=os.path.join(output_dir,output_filename)img=Image.open(input_path)ifto_format.lower()in('jpg','jpeg')andimg.modein('RGBA','P'):bg=Image.new('RGB',img.size,(255,255,255))ifimg.mode=='RGBA':bg.paste(img,mask=img.split()[3])else:bg.paste(img)img=bg save_kwargs={'quality':quality,'optimize':True}ifto_format.lower()in('jpg','jpeg')else{}img.save(output_path,**save_kwargs)count+=1print(f'格式转换完成:{count}张{from_format}→{to_format}')returncount# PNG批量转JPGconvert_format(r'C:\图片\PNG',r'C:\图片\JPG','png','jpg')有什么坑
坑1:PNG透明背景变黑色
PNG图有Alpha透明通道,直接保存JPEG时透明区域变成黑色,而非白色。
解决方法:保存前先把透明通道合并到白色背景(代码里已处理)。
坑2:CMYK格式的图片无法处理
印刷厂给的图片是CMYK颜色模式,Pillow处理某些CMYK图会出错。
解决方法:img = img.convert('RGB')先转成RGB。
坑3:图片旋转方向不对
手机拍的照片有EXIF旋转信息,Pillow默认不处理,导致某些图片显示方向不对。
解决方法:
fromPILimportImageOps img=ImageOps.exif_transpose(img)# 自动根据EXIF旋转坑4:文件名有中文导致报错
某些系统路径里的中文文件名处理有问题。
解决方法:用pathlib.Path代替字符串路径:
frompathlibimportPathforpinPath(input_dir).glob('*.png'):img=Image.open(str(p))总结
图片批量处理是Pillow最擅长的场景。压缩用二分法找quality值、调整尺寸区分fit/fill/stretch模式、格式转换注意RGBA→RGB。三个技术点搞清楚,几百张图片的处理任务几分钟搞定。