Python实现图片格式(Webp/PNG/JPG)批量互转及无损压缩

 更新时间:2026年08月31日 08:27:42   作者:小庄-Python办公  
这篇文章主要为大家详细介绍了Python如何使用Pillow库批量实现JPG、PNG、WebP等格式互转,同时通过调整quality和thumbnail压缩图片体积,有需要的小伙伴可以了解下

场景引入

  • 网站需要 WebP 格式的图片以提升加载速度
  • 客户要求 JPG 格式方便查看
  • 系统只接受 PNG 格式的图标
  • 图片太大,需要压缩后发送

手动用画图工具一张一张转换?太慢了。本节用 Python 实现批量格式转换和压缩。

技术原理

Pillow 支持几乎所有常见图片格式:

读取图片(任意格式) → PIL Image 对象 → 保存为指定格式

格式特点适用场景
JPG/JPEG有损压缩,不支持透明照片、产品图
PNG无损压缩,支持透明图标、截图
WebPGoogle 格式,体积小网页图片
BMP无压缩老系统兼容
TIFF无损,支持多层印刷、存档

环境准备

pip install Pillow

完整代码

import os
from pathlib import Path
from PIL import Image
# 支持的图片格式
SUPPORTED_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.webp', '.bmp', '.tiff', '.gif'}
# ==================== 方案 1:单个格式转换 ====================
def convert_image(input_file, output_format='jpg', quality=85, max_size=None):
    """
    转换图片格式
    参数:
        input_file: 输入图片路径
        output_format: 输出格式 'jpg'/'png'/'webp'/'bmp'
        quality: 压缩质量(1-100,仅对 jpg/webp 有效)
        max_size: 最大尺寸 (width, height) 或 None
    """
    input_path = Path(input_file)
    img = Image.open(input_path)
    # 如果需要调整大小
    if max_size:
        img.thumbnail(max_size, Image.LANCZOS)
    # 处理 RGBA → RGB(JPG 不支持透明通道)
    if output_format in ('jpg', 'jpeg', 'bmp') and img.mode == 'RGBA':
        # 白色背景替代透明
        background = Image.new('RGB', img.size, (255, 255, 255))
        background.paste(img, mask=img.split()[3])
        img = background
    # 生成输出文件名
    output_file = input_path.with_suffix(f'.{output_format}')
    # 保存参数
    save_kwargs = {}
    if output_format in ('jpg', 'jpeg'):
        save_kwargs = {'quality': quality, 'optimize': True}
    elif output_format == 'webp':
        save_kwargs = {'quality': quality, 'method': 6}
    elif output_format == 'png':
        save_kwargs = {'optimize': True}
    img.save(output_file, **save_kwargs)
    # 打印对比
    original_size = input_path.stat().st_size
    new_size = output_file.stat().st_size
    ratio = (1 - new_size / original_size) * 100
    print(f"{input_path.name} ({original_size / 1024:.1f}KB) → "
          f"{output_file.name} ({new_size / 1024:.1f}KB) "
          f"[{'+' if ratio < 0 else '-'}{abs(ratio):.1f}%]")
    return output_file
# ==================== 方案 2:批量转换 ====================
def batch_convert_folder(input_dir, output_dir, output_format='jpg', quality=85):
    """
    批量转换文件夹中的所有图片
    """
    input_path = Path(input_dir)
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)
    count = 0
    total_saved = 0
    for file_path in input_path.iterdir():
        if file_path.is_file() and file_path.suffix.lower() in SUPPORTED_EXTENSIONS:
            output_file = output_path / f"{file_path.stem}.{output_format}"
            img = Image.open(file_path)
            original_size = file_path.stat().st_size
            # 处理 RGBA → RGB
            if output_format in ('jpg', 'jpeg', 'bmp') and img.mode == 'RGBA':
                background = Image.new('RGB', img.size, (255, 255, 255))
                background.paste(img, mask=img.split()[3])
                img = background
            save_kwargs = {}
            if output_format in ('jpg', 'jpeg'):
                save_kwargs = {'quality': quality, 'optimize': True}
            elif output_format == 'webp':
                save_kwargs = {'quality': quality, 'method': 6}
            img.save(output_file, **save_kwargs)
            new_size = output_file.stat().st_size
            total_saved += original_size - new_size
            count += 1
    print(f"\n批量转换完成: {count} 张图片")
    print(f"节省空间: {total_saved / 1024 / 1024:.2f} MB")
# ==================== 方案 3:批量压缩(不改变格式) ====================
def batch_compress_images(input_dir, output_dir, quality=75, max_width=1920, max_height=1080):
    """
    批量压缩图片(保持原格式,降低质量和尺寸)
    """
    input_path = Path(input_dir)
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)
    count = 0
    total_saved = 0
    for file_path in input_path.iterdir():
        if file_path.is_file() and file_path.suffix.lower() in {'.jpg', '.jpeg', '.png', '.webp'}:
            img = Image.open(file_path)
            # 缩小尺寸
            if max_width and max_height:
                img.thumbnail((max_width, max_height), Image.LANCZOS)
            save_kwargs = {}
            if file_path.suffix.lower() in ('.jpg', '.jpeg'):
                save_kwargs = {'quality': quality, 'optimize': True}
            output_file = output_path / file_path.name
            img.save(output_file, **save_kwargs)
            original_size = file_path.stat().st_size
            new_size = output_file.stat().st_size
            total_saved += original_size - new_size
            count += 1
    print(f"批量压缩完成: {count} 张图片")
    print(f"节省空间: {total_saved / 1024 / 1024:.2f} MB")
# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 单个转换
    # convert_image("photo.png", output_format='jpg', quality=85)
    # 批量转 WebP(网页优化)
    batch_convert_folder("产品图片", "产品图片_WebP", output_format='webp', quality=80)
    # 批量压缩
    # batch_compress_images("原始照片", "压缩照片", quality=75, max_width=1920)

常见问题

Q1:GIF 动图转换后不动了?

Pillow 默认只读取 GIF 的第一帧。如需保留动画,使用 imageio

pip install imageio
import imageio

frames = imageio.mimread('animation.gif')
imageio.mimwrite('output.webp', frames, duration=0.1)

Q2:JPG 转 PNG 后体积变大很多?

JPG 是有损压缩,PNG 是无损压缩。JPG → PNG 会"放大"原本被压缩的信息。建议反向转换(PNG → JPG)来减小体积。

总结

操作方法效果
格式转换img.save('output.jpg')自动转换
压缩质量quality=75降低文件大小
缩小尺寸img.thumbnail()等比例缩放
透明处理RGBA → RGBJPG 兼容

到此这篇关于Python实现图片格式(Webp/PNG/JPG)批量互转及无损压缩的文章就介绍到这了,更多相关Python图片格式转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python的PIL对象crop函数的实现示例

    Python的PIL对象crop函数的实现示例

    PIL库的Image.crop()方法用于矩形区域裁剪,通过定义四元组坐标实现,本文就来详细的介绍一下如何使用,感兴趣的可以了解一下
    2025-12-12
  • Python3中bytes类型转换为str类型

    Python3中bytes类型转换为str类型

    Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。这篇文章主要介绍了Python3中bytes类型转换为str类型的相关知识,需要的朋友可以参考下
    2018-09-09
  • 使用Python创建一个随机密码生成器

    使用Python创建一个随机密码生成器

    密码安全是当前数字时代的一个重要议题,在保护个人信息和账户安全方面,安全且可靠的密码是至关重要的,本文将带您逐步了解如何使用Python创建一个随机密码生成器,以生成高强度、难以猜测的密码,需要的朋友可以参考下
    2024-01-01
  • 纯Python代码从零构建一个AI多智能体系统

    纯Python代码从零构建一个AI多智能体系统

    单个 AI 能做的事有限,三个 AI 分工协作能做的事远超你想象,本文介绍了如何使用Python实现一个多智能体系统,文中还提供了系统架构设计、代码实现和执行流程详解,希望对大家有所帮助
    2026-04-04
  • Python基于pygame模块播放MP3的方法示例

    Python基于pygame模块播放MP3的方法示例

    这篇文章主要介绍了Python基于pygame模块播放MP3的方法,结合实例形式简单分析了Python使用pygame模块播放MP3音频文件的实现方法以及相关函数的功能说明,需要的朋友可以参考下
    2017-09-09
  • Python Matplotlib绘图基础知识代码解析

    Python Matplotlib绘图基础知识代码解析

    这篇文章主要介绍了Python Matplotlib绘图基础知识代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 一文带你掌握Python多线程同步的核心机制与最佳实践

    一文带你掌握Python多线程同步的核心机制与最佳实践

    Python 的 threading 模块提供了多种同步原语,每种都有其特定的适用场景,本文将详细介绍这些核心机制、使用方法和最佳实践,感兴趣的小伙伴可以了解下
    2026-01-01
  • PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形

    PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形

    这篇文章主要介绍了PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统

    Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统

    这篇文章主要介绍了Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • python爬虫之基金信息存储

    python爬虫之基金信息存储

    这篇文章主要介绍了python爬虫之基金信息存储,前面已经讲了很多次要进行数据存储,终于在上一篇中完成了数据库的设,在这篇文章我们就来完成数据存储操作部分的介绍,需要的朋友可以参考一下
    2022-05-05

最新评论