在日常办公或数据处理中,我们经常需要将多张图片(如扫描件、截图、照片等)合并为一个pdf文件,方便分享或归档。虽然市面上有很多工具可以完成这一任务,但通过python脚本实现不仅灵活可控,还能根据需求定制布局(如横向/纵向、纸张大小等)。本文将介绍如何使用python的fpdf和pillow库高效实现图片转pdf,并支持中文参数和错误处理。
一、核心功能需求
在开发图片转pdf工具时,通常需要满足以下需求:
- 多图合并:支持将多张图片合并为一个pdf。
- 自定义布局:
- 支持横向或纵向页面方向。
- 支持标准纸张大小(如a4、a3)或自定义尺寸。
- 图片自适应:图片按比例缩放以适应页面,避免变形。
- 错误处理:跳过损坏的图片,保证程序稳定性。
- 中文友好:参数支持中文(如“纵向”、“横向”)。
二、技术选型
- fpdf:轻量级pdf生成库,支持自定义页面尺寸和图片插入。
- pillow(pil):图片处理库,用于获取图片尺寸和格式转换。
- glob:文件路径匹配,方便批量读取图片。
三、完整代码实现
以下是支持中文参数、自定义布局和错误处理的完整代码:
import os
import glob
from fpdf import fpdf
from pil import image
def images_to_pdf_fpdf(
image_paths,
output_pdf_path,
paper_size="a4", # 纸张大小(默认a4)
direction="纵向" # 布局方向(默认纵向,支持"横向")
):
"""
将多张图片合并为pdf,支持自定义纸张大小和方向(纵向/横向)
参数:
image_paths: 图片路径列表(支持通配符,如 '*.jpg')
output_pdf_path: 输出pdf路径
paper_size: 纸张大小(默认'a4',支持'a3'/'letter'/'legal'或自定义元组,如(200, 300))
direction: 布局方向(默认'纵向',可选'横向')
"""
# 定义标准纸张尺寸(单位:毫米)
paper_sizes = {
"a4": (210, 297),
"a3": (297, 420),
"letter": (215.9, 279.4),
"legal": (215.9, 355.6),
}
# 校验纸张大小参数
if isinstance(paper_size, str):
if paper_size.upper() in paper_sizes:
width_mm, height_mm = paper_sizes[paper_size.upper()]
else:
raise valueerror(f"未知的纸张大小: {paper_size}。支持的值: {list(paper_sizes.keys())} 或自定义元组(如 (200, 300))")
elif isinstance(paper_size, (tuple, list)) and len(paper_size) == 2:
width_mm, height_mm = paper_size
else:
raise valueerror("paper_size 必须是预定义名称(如 'a4')或 (width_mm, height_mm) 元组")
# 校验方向参数
direction = direction.lower()
if direction not in ["纵向", "横向"]:
raise valueerror("direction 必须是 '纵向' 或 '横向'")
# 根据方向调整宽高(横向时交换宽高)
if direction == "横向":
width_mm, height_mm = height_mm, width_mm
# 创建 pdf 对象
pdf = fpdf(unit="mm", format=(width_mm, height_mm)) # 直接传入宽高
for image_path in image_paths:
try:
# 打开图片并获取尺寸(转换为毫米)
img = image.open(image_path)
img_width, img_height = img.size
img_width_mm = img_width * 0.264583 # 像素 → 毫米(1像素 ≈ 0.264583毫米)
img_height_mm = img_height * 0.264583
# 计算缩放比例(适应当前页面尺寸)
scale_width = width_mm / img_width_mm
scale_height = height_mm / img_height_mm
scale = min(scale_width, scale_height)
# 计算缩放后的图片尺寸
new_width_mm = img_width_mm * scale
new_height_mm = img_height_mm * scale
# 添加页面并插入图片(居中)
pdf.add_page()
x = (width_mm - new_width_mm) / 2
y = (height_mm - new_height_mm) / 2
pdf.image(image_path, x=x, y=y, w=new_width_mm, h=new_height_mm)
except exception as e:
print(f"警告:图片 {image_path} 处理失败,跳过。错误: {e}")
# 保存 pdf
pdf.output(output_pdf_path)
print(f"pdf 已生成:{output_pdf_path}")
# 示例用法
if __name__ == "__main__":
# 获取所有jpg图片(使用raw字符串避免转义)
image_paths = glob.glob(r'e:\python\learning\图片转pdf\img\*流水.jpg')
output_pdf_path = "1-3月银行流水.pdf"
# 调用方式1:默认a4纵向
images_to_pdf_fpdf(image_paths, output_pdf_path)
# 调用方式2:a4横向
images_to_pdf_fpdf(image_paths, output_pdf_path, paper_size="a4", direction="横向")
# 调用方式3:自定义纸张大小(200x300毫米)纵向
images_to_pdf_fpdf(image_paths, output_pdf_path, paper_size=(200, 300), direction="纵向")
四、代码解析
1. 纸张大小与方向处理
- 标准纸张:通过字典
paper_sizes定义常见尺寸(如a4、a3)。 - 自定义尺寸:支持传入元组(如
(200, 300))。 - 方向调整:横向时交换宽高(
width_mm, height_mm = height_mm, width_mm)。
2. 图片自适应缩放
- 像素转毫米:1像素 ≈ 0.264583毫米。
- 缩放比例:取宽高缩放比例的最小值,确保图片完整显示。
- 居中布局:计算图片在页面中的偏移量(
x和y)。
3. 错误处理
- 捕获单张图片处理时的异常(如损坏图片),打印警告并跳过。
- 参数校验:检查
paper_size和direction的有效性。
4. 中文参数支持
- 将方向参数命名为
direction,接受"纵向"或"横向"。 - 内部统一转换为小写(
direction.lower()),避免大小写敏感问题。
五、使用场景示例
| 需求 | 调用方式 |
|---|---|
| 默认a4纵向 | images_to_pdf_fpdf(image_paths, output_pdf_path) |
| a4横向 | images_to_pdf_fpdf(image_paths, output_pdf_path, direction="横向") |
| 自定义200x300毫米纵向 | images_to_pdf_fpdf(image_paths, output_pdf_path, paper_size=(200, 300), direction="纵向") |
六、注意事项
图片方向:代码仅调整pdf页面方向,不旋转图片内容。如果图片本身是横向的,建议先用pillow旋转图片(如img.rotate(90))。
路径问题:使用glob.glob(r'...')(raw string)避免windows路径转义错误。
性能优化:对于大量图片,可考虑添加进度条(如tqdm库)。
七、总结
通过python实现图片转pdf,不仅灵活高效,还能满足个性化需求(如自定义布局、错误处理等)。本文的代码支持中文参数、标准/自定义纸张大小和横向/纵向布局,适合办公自动化场景。你可以根据实际需求进一步扩展功能(如添加水印、调整图片质量等)。
以上就是python脚本实现多张图片合并为pdf的详细内容,更多关于python图片转pdf的资料请关注代码网其它相关文章!
发表评论