《Python图片转PDF的方法介绍》
在数字化办公和文档处理的场景中,将多张图片整合为PDF文件是常见需求。PDF格式具有跨平台兼容性强、不易篡改的特点,而Python凭借其丰富的第三方库,能够高效实现图片到PDF的转换。本文将系统介绍四种主流方法,涵盖基础实现、进阶优化及特殊场景处理,帮助读者根据实际需求选择最适合的方案。
一、使用Pillow库实现基础转换
Pillow(PIL)是Python最常用的图像处理库之一,其`Image`模块提供了简单的图片转PDF功能。该方法适合处理单张图片或简单拼接多图,但无法直接调整页面布局。
1. 单张图片转PDF
from PIL import Image
def image_to_pdf_single(input_path, output_path):
"""
将单张图片转换为PDF
:param input_path: 输入图片路径(支持JPG/PNG等)
:param output_path: 输出PDF路径
"""
try:
img = Image.open(input_path)
# 确保图片为RGB模式(部分格式需转换)
if img.mode != 'RGB':
img = img.convert('RGB')
img.save(output_path, "PDF", resolution=100.0)
print(f"转换成功:{output_path}")
except Exception as e:
print(f"转换失败:{str(e)}")
# 示例调用
image_to_pdf_single("input.jpg", "output.pdf")
2. 多张图片合并为PDF
通过循环处理多张图片,需注意所有图片需统一为RGB模式且尺寸一致(或通过缩放调整):
def images_to_pdf_multi(input_paths, output_path):
"""
将多张图片合并为单个PDF
:param input_paths: 图片路径列表
:param output_path: 输出PDF路径
"""
try:
images = []
for path in input_paths:
img = Image.open(path)
if img.mode != 'RGB':
img = img.convert('RGB')
images.append(img)
if images:
images[0].save(
output_path,
"PDF",
resolution=100.0,
save_all=True,
append_images=images[1:]
)
print(f"合并成功:{output_path}")
except Exception as e:
print(f"合并失败:{str(e)}")
# 示例调用
images_to_pdf_multi(["img1.jpg", "img2.png"], "multi_output.pdf")
3. 局限性分析
Pillow的PDF功能依赖底层库(如libpdf),可能存在以下问题:
- 无法自定义页面边距或方向
- 大尺寸图片可能导致内存占用过高
- 不支持透明背景图片的Alpha通道处理
二、使用img2pdf库实现专业转换
img2pdf是专门为图片转PDF设计的库,支持更精细的控制,如保持原始DPI、处理透明通道等。
1. 基础安装与使用
pip install img2pdf
import img2pdf
def img2pdf_convert(input_paths, output_path):
"""
使用img2pdf转换图片为PDF
:param input_paths: 图片路径列表(支持排序)
:param output_path: 输出PDF路径
"""
try:
with open(output_path, "wb") as f:
f.write(img2pdf.convert(input_paths))
print(f"转换成功:{output_path}")
except Exception as e:
print(f"转换失败:{str(e)}")
# 示例调用(自动按文件名排序)
import os
input_files = sorted([f"img_{i}.jpg" for i in range(1, 4)])
img2pdf_convert(input_files, "img2pdf_output.pdf")
2. 高级参数配置
img2pdf支持通过`a4pdf`布局或自定义DPI:
def img2pdf_advanced(input_paths, output_path, dpi=300):
"""
高级转换:自定义DPI和布局
:param dpi: 输出PDF的DPI(默认300)
"""
try:
layout_fun = img2pdf.get_layout_fun(
pagesize=img2pdf.get_pagesize("A4"),
margin_left=10, # 左边距(点)
margin_right=10, # 右边距
margin_top=10, # 上边距
margin_bottom=10 # 下边距
)
with open(output_path, "wb") as f:
f.write(
img2pdf.convert(
input_paths,
dpi=dpi,
layout_fun=layout_fun
)
)
print(f"高级转换成功:{output_path}")
except Exception as e:
print(f"高级转换失败:{str(e)}")
# 示例调用
img2pdf_advanced(["img1.png", "img2.tiff"], "advanced.pdf", dpi=150)
3. 优势对比
特性 | Pillow | img2pdf |
---|---|---|
透明通道支持 | 需手动转换 | 自动处理 |
DPI控制 | 固定100 | 可自定义 |
内存效率 | 较低 | 较高(流式处理) |
三、使用fpdf2库实现定制化PDF
fpdf2是FPDF库的Python实现,允许在PDF中添加文本、表格等元素,适合需要混合内容的场景。
1. 基础图片插入
from fpdf2 import FPDF
def fpdf_basic(input_path, output_path):
"""
使用fpdf2插入单张图片
"""
pdf = FPDF()
pdf.add_page()
# 自动调整图片大小以适应页面
pdf.image(input_path, x=10, y=10, w=190) # w=宽度(mm)
pdf.output(output_path)
print(f"FPDF转换成功:{output_path}")
# 示例调用
fpdf_basic("photo.jpg", "fpdf_basic.pdf")
2. 多图片带标题布局
结合文本和图片实现更复杂的文档:
def fpdf_multi_with_text(image_paths, titles, output_path):
"""
多图片带标题的PDF
:param titles: 与图片对应的标题列表
"""
pdf = FPDF()
for img_path, title in zip(image_paths, titles):
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt=title, ln=1, align="C")
pdf.image(img_path, x=10, y=20, w=190)
pdf.output(output_path)
print(f"带标题PDF生成成功:{output_path}")
# 示例调用
images = ["cat.jpg", "dog.png"]
captions = ["猫咪照片", "狗狗照片"]
fpdf_multi_with_text(images, captions, "with_caption.pdf")
3. 适用场景
- 需要添加水印或页眉页脚
- 图片需与表格/文字混合排版
- 需要精确控制页面边距和方向
四、使用PyMuPDF(fitz)实现高性能转换
PyMuPDF是MuPDF的Python绑定,适合处理大量图片或高分辨率场景,支持内存优化和并行处理。
1. 基础安装
pip install pymupdf
2. 高效批量转换
import fitz # PyMuPDF
def pymupdf_convert(input_paths, output_path):
"""
使用PyMuPDF批量转换图片为PDF
"""
doc = fitz.open()
for path in input_paths:
img = fitz.open(path) # 以单页文档形式打开图片
pdf_bytes = img.convert_to_pdf() # 图片转为PDF字节
img_pdf = fitz.open("pdf", pdf_bytes)
doc.insert_pdf(img_pdf)
doc.save(output_path)
doc.close()
print(f"PyMuPDF转换完成:{output_path}")
# 示例调用
pymupdf_convert(["img1.jpg", "img2.bmp"], "pymupdf_out.pdf")
3. 内存优化技巧
对于超大量图片,可采用分块处理:
def pymupdf_chunked(input_paths, output_path, chunk_size=50):
"""
分块处理大量图片
:param chunk_size: 每块处理的图片数
"""
temp_pdfs = []
for i in range(0, len(input_paths), chunk_size):
chunk = input_paths[i:i+chunk_size]
doc = fitz.open()
for path in chunk:
img = fitz.open(path)
doc.insert_pdf(fitz.open("pdf", img.convert_to_pdf()))
temp_path = f"temp_{i//chunk_size}.pdf"
doc.save(temp_path)
doc.close()
temp_pdfs.append(temp_path)
# 合并临时PDF
final_doc = fitz.open()
for temp in temp_pdfs:
final_doc.insert_pdf(fitz.open(temp))
final_doc.save(output_path)
final_doc.close()
# 清理临时文件
import os
for temp in temp_pdfs:
os.remove(temp)
print(f"分块处理完成:{output_path}")
# 示例调用(处理1000张图片)
large_set = [f"img_{i}.jpg" for i in range(1000)]
pymupdf_chunked(large_set, "large_output.pdf")
五、特殊场景处理方案
1. 不同尺寸图片统一处理
通过Pillow的缩放功能统一图片尺寸:
def resize_images(input_paths, output_paths, target_size=(800, 600)):
"""
批量调整图片尺寸
:param target_size: (宽度, 高度)
"""
for in_path, out_path in zip(input_paths, output_paths):
img = Image.open(in_path)
img = img.resize(target_size, Image.LANCZOS)
if img.mode != 'RGB':
img = img.convert('RGB')
img.save(out_path)
# 示例调用
inputs = ["wide.jpg", "tall.png"]
outputs = ["resized_wide.jpg", "resized_tall.jpg"]
resize_images(inputs, outputs, (800, 600))
2. 处理透明背景图片
将PNG透明背景转为白色背景:
def png_to_pdf_with_bg(input_path, output_path, bg_color=(255, 255, 255)):
"""
处理透明PNG并转为PDF
:param bg_color: 背景色RGB元组
"""
img = Image.open(input_path).convert("RGBA")
background = Image.new("RGBA", img.size, bg_color + (255,))
composite = Image.alpha_composite(background, img)
rgb_img = composite.convert("RGB")
rgb_img.save(output_path, "PDF")
# 示例调用
png_to_pdf_with_bg("transparent.png", "solid_bg.pdf")
3. 多线程加速处理
使用`concurrent.futures`加速大量图片转换:
from concurrent.futures import ThreadPoolExecutor
def parallel_convert(input_paths, output_paths, max_workers=4):
"""
多线程并行转换
"""
def convert_single(in_path, out_path):
img = Image.open(in_path)
if img.mode != 'RGB':
img = img.convert('RGB')
img.save(out_path, "PDF")
with ThreadPoolExecutor(max_workers=max_workers) as executor:
executor.map(convert_single, input_paths, output_paths)
print("并行转换完成")
# 示例调用
inputs = [f"input_{i}.jpg" for i in range(100)]
outputs = [f"output_{i}.pdf" for i in range(100)]
parallel_convert(inputs, outputs)
六、性能对比与选型建议
方法 | 速度 | 内存 | 功能丰富度 | 适用场景 |
---|---|---|---|---|
Pillow | ★★★ | ★★☆ | ★★☆ | 简单转换 |
img2pdf | ★★★★ | ★★★★ | ★★★☆ | 专业图片PDF |
fpdf2 | ★★☆ | ★★★ | ★★★★★ | 混合文档 |
PyMuPDF | ★★★★★ | ★★★★★ | ★★★★ | 大规模处理 |
选型建议:
- 少量简单图片 → Pillow
- 高质量图片输出 → img2pdf
- 需要添加文本/表格 → fpdf2
- 超大量图片(1000+)→ PyMuPDF
关键词:Python图片转PDF、Pillow库、img2pdf、fpdf2、PyMuPDF、批量处理、透明背景、多线程
简介:本文详细介绍了使用Python将图片转换为PDF的四种主流方法,包括Pillow库的基础实现、img2pdf的专业转换、fpdf2的定制化布局以及PyMuPDF的高性能处理。覆盖了单张/多张图片转换、透明背景处理、大尺寸图片优化、并行加速等场景,并提供了性能对比和选型建议,适合不同复杂度的文档处理需求。