Python腳本實(shí)現(xiàn)多張圖片合并為PDF
在日常辦公或數(shù)據(jù)處理中,我們經(jīng)常需要將多張圖片(如掃描件、截圖、照片等)合并為一個(gè)PDF文件,方便分享或歸檔。雖然市面上有很多工具可以完成這一任務(wù),但通過(guò)Python腳本實(shí)現(xiàn)不僅靈活可控,還能根據(jù)需求定制布局(如橫向/縱向、紙張大小等)。本文將介紹如何使用Python的FPDF和Pillow庫(kù)高效實(shí)現(xiàn)圖片轉(zhuǎn)PDF,并支持中文參數(shù)和錯(cuò)誤處理。
一、核心功能需求
在開(kāi)發(fā)圖片轉(zhuǎn)PDF工具時(shí),通常需要滿足以下需求:
- 多圖合并:支持將多張圖片合并為一個(gè)PDF。
- 自定義布局:
- 支持橫向或縱向頁(yè)面方向。
- 支持標(biāo)準(zhǔn)紙張大小(如A4、A3)或自定義尺寸。
- 圖片自適應(yīng):圖片按比例縮放以適應(yīng)頁(yè)面,避免變形。
- 錯(cuò)誤處理:跳過(guò)損壞的圖片,保證程序穩(wěn)定性。
- 中文友好:參數(shù)支持中文(如“縱向”、“橫向”)。
二、技術(shù)選型
- FPDF:輕量級(jí)PDF生成庫(kù),支持自定義頁(yè)面尺寸和圖片插入。
- Pillow(PIL):圖片處理庫(kù),用于獲取圖片尺寸和格式轉(zhuǎn)換。
- glob:文件路徑匹配,方便批量讀取圖片。
三、完整代碼實(shí)現(xiàn)
以下是支持中文參數(shù)、自定義布局和錯(cuò)誤處理的完整代碼:
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", # 紙張大小(默認(rèn)A4)
direction="縱向" # 布局方向(默認(rèn)縱向,支持"橫向")
):
"""
將多張圖片合并為PDF,支持自定義紙張大小和方向(縱向/橫向)
參數(shù):
image_paths: 圖片路徑列表(支持通配符,如 '*.jpg')
output_pdf_path: 輸出PDF路徑
paper_size: 紙張大?。J(rèn)'A4',支持'A3'/'Letter'/'Legal'或自定義元組,如(200, 300))
direction: 布局方向(默認(rèn)'縱向',可選'橫向')
"""
# 定義標(biāo)準(zhǔn)紙張尺寸(單位:毫米)
paper_sizes = {
"A4": (210, 297),
"A3": (297, 420),
"Letter": (215.9, 279.4),
"Legal": (215.9, 355.6),
}
# 校驗(yàn)紙張大小參數(shù)
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 必須是預(yù)定義名稱(chēng)(如 'A4')或 (width_mm, height_mm) 元組")
# 校驗(yàn)方向參數(shù)
direction = direction.lower()
if direction not in ["縱向", "橫向"]:
raise ValueError("direction 必須是 '縱向' 或 '橫向'")
# 根據(jù)方向調(diào)整寬高(橫向時(shí)交換寬高)
if direction == "橫向":
width_mm, height_mm = height_mm, width_mm
# 創(chuàng)建 PDF 對(duì)象
pdf = FPDF(unit="mm", format=(width_mm, height_mm)) # 直接傳入寬高
for image_path in image_paths:
try:
# 打開(kāi)圖片并獲取尺寸(轉(zhuǎn)換為毫米)
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
# 計(jì)算縮放比例(適應(yīng)當(dāng)前頁(yè)面尺寸)
scale_width = width_mm / img_width_mm
scale_height = height_mm / img_height_mm
scale = min(scale_width, scale_height)
# 計(jì)算縮放后的圖片尺寸
new_width_mm = img_width_mm * scale
new_height_mm = img_height_mm * scale
# 添加頁(yè)面并插入圖片(居中)
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} 處理失敗,跳過(guò)。錯(cuò)誤: {e}")
# 保存 PDF
pdf.output(output_pdf_path)
print(f"PDF 已生成:{output_pdf_path}")
# 示例用法
if __name__ == "__main__":
# 獲取所有JPG圖片(使用raw字符串避免轉(zhuǎn)義)
image_paths = glob.glob(r'E:\Python\learning\圖片轉(zhuǎn)PDF\img\*流水.jpg')
output_pdf_path = "1-3月銀行流水.pdf"
# 調(diào)用方式1:默認(rèn)A4縱向
images_to_pdf_fpdf(image_paths, output_pdf_path)
# 調(diào)用方式2:A4橫向
images_to_pdf_fpdf(image_paths, output_pdf_path, paper_size="A4", direction="橫向")
# 調(diào)用方式3:自定義紙張大?。?00x300毫米)縱向
images_to_pdf_fpdf(image_paths, output_pdf_path, paper_size=(200, 300), direction="縱向")
四、代碼解析
1. 紙張大小與方向處理
- 標(biāo)準(zhǔn)紙張:通過(guò)字典
paper_sizes定義常見(jiàn)尺寸(如A4、A3)。 - 自定義尺寸:支持傳入元組(如
(200, 300))。 - 方向調(diào)整:橫向時(shí)交換寬高(
width_mm, height_mm = height_mm, width_mm)。
2. 圖片自適應(yīng)縮放
- 像素轉(zhuǎn)毫米:1像素 ≈ 0.264583毫米。
- 縮放比例:取寬高縮放比例的最小值,確保圖片完整顯示。
- 居中布局:計(jì)算圖片在頁(yè)面中的偏移量(
x和y)。
3. 錯(cuò)誤處理
- 捕獲單張圖片處理時(shí)的異常(如損壞圖片),打印警告并跳過(guò)。
- 參數(shù)校驗(yàn):檢查
paper_size和direction的有效性。
4. 中文參數(shù)支持
- 將方向參數(shù)命名為
direction,接受"縱向"或"橫向"。 - 內(nèi)部統(tǒng)一轉(zhuǎn)換為小寫(xiě)(
direction.lower()),避免大小寫(xiě)敏感問(wèn)題。
五、使用場(chǎng)景示例
| 需求 | 調(diào)用方式 |
|---|---|
| 默認(rèn)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="縱向") |
六、注意事項(xiàng)
圖片方向:代碼僅調(diào)整PDF頁(yè)面方向,不旋轉(zhuǎn)圖片內(nèi)容。如果圖片本身是橫向的,建議先用Pillow旋轉(zhuǎn)圖片(如img.rotate(90))。
路徑問(wèn)題:使用glob.glob(r'...')(raw string)避免Windows路徑轉(zhuǎn)義錯(cuò)誤。
性能優(yōu)化:對(duì)于大量圖片,可考慮添加進(jìn)度條(如tqdm庫(kù))。
七、總結(jié)
通過(guò)Python實(shí)現(xiàn)圖片轉(zhuǎn)PDF,不僅靈活高效,還能滿足個(gè)性化需求(如自定義布局、錯(cuò)誤處理等)。本文的代碼支持中文參數(shù)、標(biāo)準(zhǔn)/自定義紙張大小和橫向/縱向布局,適合辦公自動(dòng)化場(chǎng)景。你可以根據(jù)實(shí)際需求進(jìn)一步擴(kuò)展功能(如添加水印、調(diào)整圖片質(zhì)量等)。
以上就是Python腳本實(shí)現(xiàn)多張圖片合并為PDF的詳細(xì)內(nèi)容,更多關(guān)于Python圖片轉(zhuǎn)PDF的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python實(shí)現(xiàn)制作透明背景的電子印章
這篇文章主要為大家詳細(xì)介紹了如何利用Python語(yǔ)言實(shí)現(xiàn)制作透明背景的電子印章,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-09-09
Python實(shí)現(xiàn)的計(jì)數(shù)排序算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)的計(jì)數(shù)排序算法,簡(jiǎn)單描述了計(jì)數(shù)排序的算法原理并結(jié)合具體實(shí)例形式分析了Python計(jì)數(shù)排序的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下2017-11-11
Python爬蟲(chóng)爬取博客實(shí)現(xiàn)可視化過(guò)程解析
這篇文章主要介紹了Python爬蟲(chóng)爬取博客實(shí)現(xiàn)可視化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
python中的十大%占位符對(duì)應(yīng)的格式化的使用方法
本文主要介紹了python中的十大%占位符對(duì)應(yīng)的格式化的使用方法,它可以很好的幫助我們解決一些字符串格式化的問(wèn)題, 文中通過(guò)示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下2022-01-01
使用Python腳本實(shí)現(xiàn)同一個(gè)Git倉(cāng)庫(kù)在多個(gè)機(jī)房及多臺(tái)電腦上同時(shí)同步
本文介紹了一個(gè)Python腳本,用于在多臺(tái)機(jī)器上同步Git倉(cāng)庫(kù),通過(guò)中心控制節(jié)點(diǎn)并發(fā)SSH到各機(jī)器執(zhí)行g(shù)it pull或clone命令,支持SSH密鑰或密碼登錄,配置需修改倉(cāng)庫(kù)地址、目標(biāo)路徑和機(jī)器列表,適用于跨機(jī)房代碼同步場(chǎng)景,需要的朋友可以參考下2026-04-04
Python獲取電腦硬件信息及狀態(tài)的實(shí)現(xiàn)方法
這篇文章主要介紹了Python獲取電腦硬件信息及狀態(tài)的實(shí)現(xiàn)方法,是一個(gè)很實(shí)用的技巧,需要的朋友可以參考下2014-08-08
淺談Django中的數(shù)據(jù)庫(kù)模型類(lèi)-models.py(一對(duì)一的關(guān)系)
今天小編就為大家分享一篇淺談Django中的數(shù)據(jù)庫(kù)模型類(lèi)-models.py(一對(duì)一的關(guān)系),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
python檢查目錄文件權(quán)限并修改目錄文件權(quán)限的操作
這篇文章主要介紹了python檢查目錄文件權(quán)限并修改目錄文件權(quán)限的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03

