在日常开发中,图片格式转换是一个高频需求——上传前压缩体积、适配不同平台的格式要求、生成缩略图……手动一张张改?不存在的。Python 几行代码就能搞定。

本文覆盖主流转换场景,提供可直接运行的代码,拿来就能用。

一、先搞清楚:常见图片格式有哪些?

格式 特点 典型场景
JPG/JPEG 有损压缩,体积小,不支持透明 照片、网页配图
PNG 无损压缩,支持透明通道 图标、截图、需要透明背景的图
GIF 支持动画,256色 表情包、简单动画
WebP Google 出品,体积比 JPG 小 30%+ 网站优化(Chrome 全面支持)
BMP 无压缩,体积巨大 几乎不用,仅特殊场景
TIFF 高质量,多用于印刷 专业摄影、印刷

核心结论:大部分场景只需要在 JPG、PNG、WebP 三者之间转换。

二、工具选型:用哪个库?

适用场景 优点 缺点
Pillow(PIL) 通用转换,最推荐 简单、稳定、文档全 大批量时稍慢
OpenCV(cv2) 需要同时做图像处理 功能强大 依赖多,安装重
imageio 读写 GIF/WebP 动画 动画支持好 依赖 ffmpeg
Pillow-SIMD 追求速度 比 Pillow 快 2-4 倍 需要单独安装

90% 的场景用 Pillow 就够了。

安装:

pip install Pillow

三、基础转换:一行代码搞定

1. PNG → JPG

from PIL import Image

img = Image.open("input.png")
# PNG 有透明通道,JPG 不支持,必须转 RGB
rgb_img = img.convert("RGB")
rgb_img.save("output.jpg", quality=95)

关键坑:PNG 转 JPG 必须先 .convert("RGB"),否则报错或出黑底。

2. JPG → PNG

from PIL import Image

img = Image.open("input.jpg")
img.save("output.png")

这个不用特殊处理,直接转。

3. 任意格式 → WebP(推荐用于网页)

from PIL import Image

img = Image.open("input.png")
img.save("output.webp", quality=80)

WebP 的 quality 参数范围 0-100,80 是体积和质量的 sweet spot。

四、批量转换:一个文件夹全搞定

这才是真实需求。一次性转换整个目录:

import os
from PIL import Image

def batch_convert(input_dir, output_dir, target_format="jpg", quality=90):
    """
    批量转换图片格式
    :param input_dir: 输入目录
    :param output_dir: 输出目录
    :param target_format: 目标格式(jpg/png/webp)
    :param quality: JPG/WebP 质量(1-100)
    """
    os.makedirs(output_dir, exist_ok=True)
    
    supported = {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".webp", ".tiff"}
    
    for filename in os.listdir(input_dir):
        if not any(filename.lower().endswith(ext) for ext in supported):
            continue
        
        input_path = os.path.join(input_dir, filename)
        name, _ = os.path.splitext(filename)
        output_path = os.path.join(output_dir, f"{name}.{target_format}")
        
        try:
            with Image.open(input_path) as img:
                # 处理透明通道
                if target_format in ("jpg", "jpeg"):
                    img = img.convert("RGB")
                elif target_format == "webp":
                    img = img.convert("RGBA")  # WebP 支持透明
                
                save_kwargs = {"quality": quality} if target_format in ("jpg", "webp") else {}
                img.save(output_path, **save_kwargs)
                
            print(f"✅ {filename} → {name}.{target_format}")
        except Exception as e:
            print(f"❌ {filename} 失败: {e}")

# 使用
batch_convert("./images", "./converted", target_format="webp", quality=80)

五、进阶:转换时顺便压缩

很多时候转换格式就是为了减小体积。直接在转换时控制:

from PIL import Image

def compress_and_convert(input_path, output_path, target_format="jpg", max_size=(800, 800)):
    """转换格式 + 限制尺寸 + 压缩质量"""
    with Image.open(input_path) as img:
        # 限制最大尺寸(保持比例)
        img.thumbnail(max_size, Image.LANCZOS)
        
        if target_format in ("jpg", "jpeg"):
            img = img.convert("RGB")
            img.save(output_path, quality=75, optimize=True)
        elif target_format == "webp":
            img.save(output_path, quality=75, method=6)  # method=6 是最高压缩
        else:
            img.save(output_path)

compress_and_convert("photo.png", "photo_small.webp")

optimize=True 和 method=6 能让 JPG/WebP 再小 10-20%,强烈建议加上。

六、GIF 动画转换

GIF 稍微特殊一点,需要逐帧处理:

from PIL import Image

def gif_to_frames(gif_path, output_dir):
    """把 GIF 拆成 PNG 帧"""
    os.makedirs(output_dir, exist_ok=True)
    img = Image.open(gif_path)
    
    for i, frame in enumerate(ImageSequence.Iterator(img)):
        frame.save(os.path.join(output_dir, f"frame_{i:03d}.png"))

def frames_to_gif(frames_dir, output_gif, duration=100):
    """把 PNG 帧合成 GIF(duration 单位:毫秒)"""
    frames = []
    for f in sorted(os.listdir(frames_dir)):
        if f.endswith(".png"):
            frames.append(Image.open(os.path.join(frames_dir, f)))
    
    frames[0].save(
        output_gif,
        save_all=True,
        append_images=frames[1:],
        duration=duration,
        loop=0
    )

七、性能对比:Pillow vs Pillow-SIMD

场景 Pillow Pillow-SIMD
单张转换 ~50ms ~20ms
1000 张 JPG→WebP ~45s ~15s

如果你要处理上万张图,装 Pillow-SIMD:

pip uninstall Pillow
pip install Pillow-SIMD

代码完全一样,直接替换,不用改任何逻辑。

八、选型决策树

需要转格式?
├── 单纯转格式 → Pillow
├── 还要裁剪/加水印/滤镜 → OpenCV
├── GIF 动画处理 → imageio 或 Pillow
├── 批量 > 1000 张 → Pillow-SIMD
└── Web 优化为主 → Pillow 转 WebP,quality=80

总结

需求 推荐方案
单张快速转换 Image.open().save()
批量转换文件夹 上面的 batch_convert() 函数
网页图片优化 转 WebP,quality=80,optimize=True
PNG 转 JPG 必须.convert("RGB")
追求速度 Pillow-SIMD

图片转换这件事,Python 能做到的远不止格式互转——压缩、缩放、加水印都能一把梭。先把格式转换这一步打通,后面的处理就是加几行代码的事。

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章

1 2 3 4 5