Python+Ghostscript實現(xiàn)一個簡單的PDF批量壓縮工具(含進度條)
在日常工作中,我們經(jīng)常會遇到 PDF 文件體積過大的問題:要么發(fā)郵件超出限制、要么上傳系統(tǒng)被拒絕、要么手機查看太慢。
手動一個個壓縮不僅麻煩,還容易忘參數(shù)。今天分享一個用 Python + Ghostscript 實現(xiàn)的 自動批量壓縮 PDF 腳本,支持:
- 智能推薦壓縮等級
- 進度條顯示
- 記憶上次選擇
- 跨平臺(Windows / macOS / Linux)
一、腳本功能概覽
腳本主要做了以下幾件事:
- 自動檢測 Ghostscript 是否安裝
- 掃描指定目錄下所有 PDF 文件
- 根據(jù)文件總大小 智能推薦 壓縮等級
- 用戶可手動選擇壓縮模式(共 5 種)
- 逐個壓縮 PDF 文件并顯示進度條
- 統(tǒng)計壓縮結(jié)果、計算壓縮率、輸出報告
二、Ghostscript 簡介
Ghostscript (gs) 是一款強大的 PDF 與 PostScript 處理工具,幾乎所有 PDF 壓縮軟件(包括 Adobe Acrobat)都基于它。
安裝方式如下:
Windows:官方下載地址
macOS(Homebrew):
brew install ghostscript
Linux(Debian/Ubuntu):
sudo apt install ghostscript
安裝完成后,執(zhí)行命令驗證:
gs --version
三、完整 Python 腳本
保存為 pdf_compress.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, subprocess, sys, platform, shutil, json
from tqdm import tqdm
# ===== 配置 =====
input_dir = "output_pdfs" # 待壓縮PDF目錄
output_dir = "pdf_output" # 輸出目錄
config_file = "compress_config.json" # 保存上次選擇
# ===== 壓縮等級定義 =====
COMPRESSION_LEVELS = {
"1": { "name": "屏幕 (72dpi)", "level": "/screen", "desc": "網(wǎng)頁/手機,超小文件" },
"2": { "name": "電子書 (150dpi)", "level": "/ebook", "desc": "閱讀,平衡大小" },
"3": { "name": "打印 (300dpi)", "level": "/printer", "desc": "打印,高清" },
"4": { "name": "印刷 (300+dpi)", "level": "/prepress", "desc": "專業(yè)印刷,保真" },
"5": { "name": "無損優(yōu)化", "level": "/default", "desc": "僅優(yōu)化結(jié)構(gòu),不降質(zhì)量" }
}
# ===== 保存/加載配置 =====
def load_last_config():
try:
with open(config_file, 'r') as f:
return json.load(f).get('level', '2')
except:
return '2'
def save_config(level):
with open(config_file, 'w') as f:
json.dump({'level': level}, f)
# ===== 工具函數(shù) =====
def get_file_size_mb(path):
try:
return os.path.getsize(path) / (1024 * 1024)
except:
return 0
def recommend_level(pdf_files):
total_size = sum(get_file_size_mb(os.path.join(input_dir, f)) for f in pdf_files)
if total_size > 50:
return "1"
elif total_size > 10:
return "2"
else:
return "3"
# ===== 檢測 Ghostscript =====
def find_gs_command():
system = platform.system()
candidates = ["gswin64c", "gswin32c", "gs"] if system == "Windows" else ["gs"]
for cmd in candidates:
if shutil.which(cmd):
return cmd
return None
gs_cmd = find_gs_command()
if not gs_cmd:
print("? 未找到 Ghostscript!請先安裝。")
sys.exit(1)
print(f"? Ghostscript: `{gs_cmd}`")
os.makedirs(output_dir, exist_ok=True)
# ===== 獲取 PDF 文件 =====
pdf_files = [f for f in os.listdir(input_dir)
if f.lower().endswith(".pdf") and os.path.isfile(os.path.join(input_dir, f))]
if not pdf_files:
print(f"? `{input_dir}` 中未找到 PDF 文件")
sys.exit(0)
total_size = sum(get_file_size_mb(os.path.join(input_dir, f)) for f in pdf_files)
print(f"?? 發(fā)現(xiàn) {len(pdf_files)} 個 PDF,總大小: {total_size:.1f}MB")
# ===== 選擇壓縮等級 =====
print("\n" + "="*60)
print("?? 請選擇壓縮等級 (上次選擇: {})".format(load_last_config()))
print("="*60)
for key, info in COMPRESSION_LEVELS.items():
print(f" {key}. {info['name']} - {info['desc']}")
print("="*60)
recommended = recommend_level(pdf_files)
print(f"?? 智能推薦: {recommended} (基于文件大小)")
while True:
choice = input("\n請輸入編號 (1-5): ").strip()
if choice in COMPRESSION_LEVELS:
compression_level = COMPRESSION_LEVELS[choice]["level"]
selected_name = COMPRESSION_LEVELS[choice]["name"]
save_config(choice)
break
else:
print("? 請輸入 1-5")
print(f"\n?? 確認使用: {selected_name}")
# ===== 批量壓縮 =====
failed = []
pbar = tqdm(pdf_files, desc="壓縮進度", unit="文件")
for pdf_file in pbar:
input_path = os.path.join(input_dir, pdf_file)
output_path = os.path.join(output_dir, pdf_file)
pbar.set_postfix({"文件": pdf_file[:30]})
cmd = [
gs_cmd, "-sDEVICE=pdfwrite", "-dCompatibilityLevel=1.4",
f"-dPDFSETTINGS={compression_level}", "-dNOPAUSE", "-dQUIET", "-dBATCH",
f"-sOutputFile={output_path}", input_path
]
try:
subprocess.run(cmd, check=True, capture_output=True)
except subprocess.CalledProcessError:
failed.append(pdf_file)
# ===== 輸出結(jié)果 =====
success = len(pdf_files) - len(failed)
orig_total = sum(get_file_size_mb(os.path.join(input_dir, f)) for f in pdf_files)
comp_total = sum(get_file_size_mb(os.path.join(output_dir, f)) for f in os.listdir(output_dir) if f.lower().endswith('.pdf'))
print("\n" + "="*60)
print("?? 壓縮完成!")
print("="*60)
print(f"?? 成功: {success}/{len(pdf_files)}")
print(f"?? 原始: {orig_total:.1f}MB → 壓縮后: {comp_total:.1f}MB")
print(f"?? 壓縮率: {((orig_total-comp_total)/orig_total*100):.1f}%")
print(f"?? 輸出目錄: {os.path.abspath(output_dir)}")
if failed:
print(f"\n? 失敗文件 ({len(failed)}):")
for f in failed:
print(f" - {f}")
print("="*60)
四、壓縮等級說明
| 等級 | 模式 | 分辨率 | 說明 |
|---|---|---|---|
| 1 | /screen | 72dpi | 適合網(wǎng)頁、手機端,體積最小 |
| 2 | /ebook | 150dpi | 適合電子閱讀,畫質(zhì)平衡 |
| 3 | /printer | 300dpi | 打印清晰,常用推薦 |
| 4 | /prepress | 300+dpi | 出版印刷級 |
| 5 | /default | 無損 | 不降質(zhì),僅結(jié)構(gòu)優(yōu)化 |
五、運行效果
運行:
python3 pdf_compress.py
輸出示例:
? Ghostscript: `gs`
?? 發(fā)現(xiàn) 8 個 PDF,總大小: 42.5MB
?? 智能推薦: 2 (基于文件大小)
?? 確認使用: 電子書 (150dpi)
壓縮進度: 100%|████████████████████| 8/8 [00:12<00:00, 0.65文件/s]
?? 壓縮完成!
?? 原始: 42.5MB → 壓縮后: 15.3MB
?? 壓縮率: 64.0%
?? 輸出目錄: /home/user/pdf_output
到此這篇關(guān)于Python+Ghostscript實現(xiàn)一個簡單的PDF批量壓縮工具(含進度條)的文章就介紹到這了,更多相關(guān)Python PDF批量壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python基于pyDes庫實現(xiàn)des加密的方法
這篇文章主要介紹了python基于pyDes庫實現(xiàn)des加密的方法,結(jié)合實例形式較為詳細的分析了pyDes庫的下載、安裝及使用pyDes庫進行加密的相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
使用Python給Excel工作表設(shè)置背景色或背景圖
Excel是工作中數(shù)據(jù)處理和分析數(shù)據(jù)的重要工具,面對海量的數(shù)據(jù)和復(fù)雜的表格,如何提高工作效率、減少視覺疲勞并提升數(shù)據(jù)的可讀性是不容忽視的問題,而給工作表設(shè)置合適的背景是表格優(yōu)化的一個有效方式,本文將介紹如何用Python給Excel工作表設(shè)置背景色或背景圖2024-07-07
python3實現(xiàn)將json對象存入Redis以及數(shù)據(jù)的導(dǎo)入導(dǎo)出
這篇文章主要介紹了python3實現(xiàn)將json對象存入Redis以及數(shù)據(jù)的導(dǎo)入導(dǎo)出,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
tensorflow創(chuàng)建變量以及根據(jù)名稱查找變量
這篇文章主要為大家詳細介紹了tensorflow創(chuàng)建變量以及根據(jù)名稱查找變量,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03
在服務(wù)器上安裝python3.8.2環(huán)境的教程詳解
這篇文章主要介紹了在服務(wù)器上安裝python3.8.2環(huán)境的教程詳解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
Python數(shù)據(jù)可視化常用4大繪圖庫原理詳解
這篇文章主要介紹了Python數(shù)據(jù)可視化常用4大繪圖庫原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10

