公司动态
Python办公20:图片格式转换——Webp/PNG/JPG 批量互转及无损压缩
20图片格式转换——Webp/PNG/JPG 批量互转及无损压缩第三阶段PDF 与图片处理16-22场景引入网站需要 WebP 格式的图片以提升加载速度客户要求 JPG 格式方便查看系统只接受 PNG 格式的图标图片太大需要压缩后发送手动用画图工具一张一张转换太慢了。本节用 Python 实现批量格式转换和压缩。技术原理Pillow 支持几乎所有常见图片格式读取图片任意格式 → PIL Image 对象 → 保存为指定格式格式特点适用场景JPG/JPEG有损压缩不支持透明照片、产品图PNG无损压缩支持透明图标、截图WebPGoogle 格式体积小网页图片BMP无压缩老系统兼容TIFF无损支持多层印刷、存档环境准备pipinstallPillow完整代码importosfrompathlibimportPathfromPILimportImage# 支持的图片格式SUPPORTED_EXTENSIONS{.jpg,.jpeg,.png,.webp,.bmp,.tiff,.gif}# 方案 1单个格式转换 defconvert_image(input_file,output_formatjpg,quality85,max_sizeNone): 转换图片格式 参数: input_file: 输入图片路径 output_format: 输出格式 jpg/png/webp/bmp quality: 压缩质量1-100仅对 jpg/webp 有效 max_size: 最大尺寸 (width, height) 或 None input_pathPath(input_file)imgImage.open(input_path)# 如果需要调整大小ifmax_size:img.thumbnail(max_size,Image.LANCZOS)# 处理 RGBA → RGBJPG 不支持透明通道ifoutput_formatin(jpg,jpeg,bmp)andimg.modeRGBA:# 白色背景替代透明backgroundImage.new(RGB,img.size,(255,255,255))background.paste(img,maskimg.split()[3])imgbackground# 生成输出文件名output_fileinput_path.with_suffix(f.{output_format})# 保存参数save_kwargs{}ifoutput_formatin(jpg,jpeg):save_kwargs{quality:quality,optimize:True}elifoutput_formatwebp:save_kwargs{quality:quality,method:6}elifoutput_formatpng:save_kwargs{optimize:True}img.save(output_file,**save_kwargs)# 打印对比original_sizeinput_path.stat().st_size new_sizeoutput_file.stat().st_size ratio(1-new_size/original_size)*100print(f{input_path.name}({original_size/1024:.1f}KB) → f{output_file.name}({new_size/1024:.1f}KB) f[{ifratio0else-}{abs(ratio):.1f}%])returnoutput_file# 方案 2批量转换 defbatch_convert_folder(input_dir,output_dir,output_formatjpg,quality85): 批量转换文件夹中的所有图片 input_pathPath(input_dir)output_pathPath(output_dir)output_path.mkdir(parentsTrue,exist_okTrue)count0total_saved0forfile_pathininput_path.iterdir():iffile_path.is_file()andfile_path.suffix.lower()inSUPPORTED_EXTENSIONS:output_fileoutput_path/f{file_path.stem}.{output_format}imgImage.open(file_path)original_sizefile_path.stat().st_size# 处理 RGBA → RGBifoutput_formatin(jpg,jpeg,bmp)andimg.modeRGBA:backgroundImage.new(RGB,img.size,(255,255,255))background.paste(img,maskimg.split()[3])imgbackground save_kwargs{}ifoutput_formatin(jpg,jpeg):save_kwargs{quality:quality,optimize:True}elifoutput_formatwebp:save_kwargs{quality:quality,method:6}img.save(output_file,**save_kwargs)new_sizeoutput_file.stat().st_size total_savedoriginal_size-new_size count1print(f\n批量转换完成:{count}张图片)print(f节省空间:{total_saved/1024/1024:.2f}MB)# 方案 3批量压缩不改变格式 defbatch_compress_images(input_dir,output_dir,quality75,max_width1920,max_height1080): 批量压缩图片保持原格式降低质量和尺寸 input_pathPath(input_dir)output_pathPath(output_dir)output_path.mkdir(parentsTrue,exist_okTrue)count0total_saved0forfile_pathininput_path.iterdir():iffile_path.is_file()andfile_path.suffix.lower()in{.jpg,.jpeg,.png,.webp}:imgImage.open(file_path)# 缩小尺寸ifmax_widthandmax_height:img.thumbnail((max_width,max_height),Image.LANCZOS)save_kwargs{}iffile_path.suffix.lower()in(.jpg,.jpeg):save_kwargs{quality:quality,optimize:True}output_fileoutput_path/file_path.name img.save(output_file,**save_kwargs)original_sizefile_path.stat().st_size new_sizeoutput_file.stat().st_size total_savedoriginal_size-new_size count1print(f批量压缩完成:{count}张图片)print(f节省空间:{total_saved/1024/1024:.2f}MB)# 使用示例 if__name____main__:# 单个转换# convert_image(photo.png, output_formatjpg, quality85)# 批量转 WebP网页优化batch_convert_folder(产品图片,产品图片_WebP,output_formatwebp,quality80)# 批量压缩# batch_compress_images(原始照片, 压缩照片, quality75, max_width1920)常见问题Q1GIF 动图转换后不动了Pillow默认只读取 GIF 的第一帧。如需保留动画使用imageiopipinstallimageioimportimageio framesimageio.mimread(animation.gif)imageio.mimwrite(output.webp,frames,duration0.1)Q2JPG 转 PNG 后体积变大很多JPG 是有损压缩PNG 是无损压缩。JPG → PNG 会放大原本被压缩的信息。建议反向转换PNG → JPG来减小体积。总结操作方法效果格式转换img.save(output.jpg)自动转换压缩质量quality75降低文件大小缩小尺寸img.thumbnail()等比例缩放透明处理RGBA → RGBJPG 兼容本节掌握了图片格式批量转换和压缩的能力。下一节预告21表格提取——从 PDF 扫描件中自动抓取表格数据至 Excel