You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提升Pillow实现多格式图片转PNG的处理速度?

基于Pillow的图片转PNG提速方案

针对你用Pillow处理PDF提取图片转PNG时单线程速度慢的问题,以下是几种保留Pillow生态的提速方法:

1. 并行处理(多进程/多线程)

图片转换属于CPU密集型任务,受Python GIL限制,多进程更适合批量处理场景。可以用concurrent.futures.ProcessPoolExecutor实现并行转换:

import concurrent.futures
import os
import io
from PIL import Image

def convert_to_png(image_bytes, filename):
    try:
        with Image.open(io.BytesIO(image_bytes)) as img:
            png_filename = os.path.splitext(filename)[0] + '.png'
            # 优化:仅当必要时转换为RGBA
            if img.mode not in ('RGB', 'RGBA'):
                img = img.convert('RGBA')
            # 降低压缩级别提升保存速度
            img.save(png_filename, 'PNG', compress_level=1)
            return png_filename
    except Exception as e:
        print(f"Error converting {filename}: {str(e)}")
        return None

# 批量处理示例
def batch_convert(image_data_list):
    # image_data_list是包含(image_bytes, filename)的元组列表
    with concurrent.futures.ProcessPoolExecutor() as executor:
        # 提交所有任务
        futures = [executor.submit(convert_to_png, data[0], data[1]) for data in image_data_list]
        # 获取结果
        results = [future.result() for future in concurrent.futures.as_completed(futures)]
    return results

2. 优化Pillow内部参数

  • 避免不必要的颜色模式转换:原函数强制转RGBA,如果原图片是RGB、灰度等可直接保存为PNG的格式,跳过转换能节省大量时间。
  • 调整PNG压缩级别:save方法的compress_level参数(0-9,默认6),降低级别(如1-3)能大幅提升保存速度,代价是文件体积略有增大,对于批量处理场景性价比很高。

3. 使用SIMD优化版本的Pillow

替换为pillow-simd,这是Pillow的官方优化分支,针对x86/x86_64架构的CPU做了SIMD指令集优化(如AVX2、SSE),图片处理速度可提升2-4倍,API与原生Pillow完全兼容,无需修改现有代码:

pip uninstall pillow
pip install pillow-simd

4. 减少磁盘IO开销

  • 如果后续流程不需要磁盘文件,可直接在内存中生成PNG字节流,避免磁盘读写等待:
def convert_to_png_in_memory(image_bytes):
    try:
        with Image.open(io.BytesIO(image_bytes)) as img:
            if img.mode not in ('RGB', 'RGBA'):
                img = img.convert('RGBA')
            buffer = io.BytesIO()
            img.save(buffer, 'PNG', compress_level=1)
            return buffer.getvalue()
    except Exception as e:
        print(f"Error converting image: {str(e)}")
        return None
  • 批量处理时,尽量将文件写入操作集中到同一磁盘分区,减少磁盘寻道时间。

5. 按需缩小图片尺寸

如果业务场景不需要保留原始图片的高分辨率,可先缩小图片再转换,减少像素处理量:

def convert_to_png_resized(image_bytes, filename, max_size=(1920, 1080)):
    try:
        with Image.open(io.BytesIO(image_bytes)) as img:
            img.thumbnail(max_size)  # 按比例缩小到指定尺寸
            png_filename = os.path.splitext(filename)[0] + '.png'
            if img.mode not in ('RGB', 'RGBA'):
                img = img.convert('RGBA')
            img.save(png_filename, 'PNG', compress_level=1)
            return png_filename
    except Exception as e:
        print(f"Error converting {filename}: {str(e)}")
        return None

内容的提问来源于stack exchange,提问作者Sereno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:55:11