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

如何将大量JPG图片转为Web优化的极小体积PDF?

图片转小体积PDF优化方案

问题背景

有2000张单张约150KB、96dpi的图片,需转换为体积尽可能小的PDF,但使用PyPDF2生成的PDF体积超大(约800000MB),原代码如下:

for i in range(0, noImages):
  image = Image.open(newimageList[i])

  if(i == 0):                       
    image.save(namePath, "PDF" ,quality=100, optimize=True, save_all=True)
  else:
    namePath2 = rootPDF+pdf_id+"temp.pdf"
    image.save(namePath2, "PDF" ,quality=100, optimize=True, save_all=True)

    pdfs = [namePath, namePath2]

    merger = PdfFileMerger()
    for f in pdfs:
        merger.append(PdfFileReader(f), 'rb')
    with open(namePath, 'wb') as new_file:
        merger.write(new_file)
    os.remove(namePath2)

问题分析

原代码的核心问题:

  • 每次循环都合并PDF,反复写入会产生大量冗余数据,导致体积暴增
  • 保存PDF时设置quality=100,几乎没有对图片进行压缩
  • 未处理带透明通道的图片(如PNG),这类图片转PDF时会额外占用空间

优化方案

1. 一次性批量生成PDF(最核心优化)

直接加载所有图片后一次性保存,避免反复合并操作,同时调整压缩参数:

from PIL import Image
import os

# 批量加载并处理图片
processed_images = []
for img_path in newimageList:
    img = Image.open(img_path)
    # 将带透明通道的图片转为RGB格式
    if img.mode in ('RGBA', 'P'):
        img = img.convert('RGB')
    processed_images.append(img)

# 一次性生成PDF
if processed_images:
    processed_images[0].save(
        namePath,
        format="PDF",
        quality=60,  # 可根据需求调整,50-70区间兼顾体积和清晰度
        optimize=True,
        save_all=True,
        append_images=processed_images[1:]  # 直接追加所有后续图片
    )

2. 先压缩图片再转PDF(进一步减小体积)

如果图片仍有压缩空间,可先对图片进行分辨率和质量压缩:

from PIL import Image
import os

def process_image(img_path, target_quality=60, target_dpi=96):
    img = Image.open(img_path)
    # 转换为RGB格式
    if img.mode in ('RGBA', 'P'):
        img = img.convert('RGB')
    # 统一设置分辨率
    img.info['dpi'] = (target_dpi, target_dpi)
    return img

# 处理所有图片
processed_images = [process_image(path) for path in newimageList]

# 生成PDF
if processed_images:
    processed_images[0].save(
        namePath,
        format="PDF",
        quality=target_quality,
        optimize=True,
        save_all=True,
        append_images=processed_images[1:]
    )

3. 用PyMuPDF二次压缩PDF(可选)

如果生成的PDF体积仍不符合预期,可使用PyMuPDF对成品PDF进一步压缩:

import fitz

def compress_pdf(input_pdf, output_pdf):
    doc = fitz.open(input_pdf)
    # 遍历每页压缩图片
    for page in doc:
        pix = page.get_pixmap()
        # 设置分辨率为96dpi,图片质量60
        pix.set_dpi(96, 96)
        pix.save("temp_img.jpg", quality=60)
        # 替换页内图片
        page.insert_image(page.rect, filename="temp_img.jpg")
    # 保存压缩后的PDF,启用垃圾回收和压缩
    doc.save(output_pdf, garbage=4, deflate=True)
    doc.close()
    os.remove("temp_img.jpg")

# 调用示例:先生成PDF,再压缩
compress_pdf(namePath, f"compressed_{namePath}")

关键优化点总结

  • 避免反复合并PDF:一次性追加所有图片,消除冗余数据
  • 降低图片质量:quality=100无压缩,调整到50-70可大幅减小体积
  • 处理透明通道图片:转RGB格式避免额外空间占用
  • 选择高效工具:PIL批量生成比PyPDF2合并更高效,PyMuPDF压缩能力更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:06:04