当前位置: 代码网 > it编程>前端脚本>Python > Python+Ghostscript实现一个简单的PDF批量压缩工具(含进度条)

Python+Ghostscript实现一个简单的PDF批量压缩工具(含进度条)

2025年11月27日 Python 我要评论
在日常工作中,我们经常会遇到 pdf 文件体积过大的问题:要么发邮件超出限制、要么上传系统被拒绝、要么手机查看太慢。手动一个个压缩不仅麻烦,还容易忘参数。今天分享一个用 python + ghosts

在日常工作中,我们经常会遇到 pdf 文件体积过大的问题:要么发邮件超出限制、要么上传系统被拒绝、要么手机查看太慢。

手动一个个压缩不仅麻烦,还容易忘参数。今天分享一个用 python + ghostscript 实现的 自动批量压缩 pdf 脚本,支持:

  • 智能推荐压缩等级
  • 进度条显示
  • 记忆上次选择
  • 跨平台(windows / macos / linux)

一、脚本功能概览

脚本主要做了以下几件事:

  • 自动检测 ghostscript 是否安装
  • 扫描指定目录下所有 pdf 文件
  • 根据文件总大小 智能推荐 压缩等级
  • 用户可手动选择压缩模式(共 5 种)
  • 逐个压缩 pdf 文件并显示进度条
  • 统计压缩结果、计算压缩率、输出报告

二、ghostscript 简介

ghostscript (gs) 是一款强大的 pdf 与 postscript 处理工具,几乎所有 pdf 压缩软件(包括 adobe acrobat)都基于它。

安装方式如下:

windows:官方下载地址

macos(homebrew):

brew install ghostscript 

linux(debian/ubuntu):

sudo apt install ghostscript 

安装完成后,执行命令验证:

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": "网页/手机,超小文件" },
    "2": { "name": "电子书 (150dpi)", "level": "/ebook",    "desc": "阅读,平衡大小" },
    "3": { "name": "打印 (300dpi)", "level": "/printer",  "desc": "打印,高清" },
    "4": { "name": "印刷 (300+dpi)", "level": "/prepress", "desc": "专业印刷,保真" },
    "5": { "name": "无损优化", "level": "/default",   "desc": "仅优化结构,不降质量" }
}

# ===== 保存/加载配置 =====
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)

# ===== 工具函数 =====
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"📁 发现 {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)

# ===== 输出结果 =====
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/screen72dpi适合网页、手机端,体积最小
2/ebook150dpi适合电子阅读,画质平衡
3/printer300dpi打印清晰,常用推荐
4/prepress300+dpi出版印刷级
5/default无损不降质,仅结构优化

五、运行效果

运行:

python3 pdf_compress.py

输出示例:

✅ ghostscript: `gs`
📁 发现 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

到此这篇关于python+ghostscript实现一个简单的pdf批量压缩工具(含进度条)的文章就介绍到这了,更多相关python pdf批量压缩内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com