
PDF 压缩这件事绝大多数人第一次接触是从“文件太大传不出去”开始的。单个文件还好说随便找个在线工具就能解决但如果手上是几十个、上百个 PDF逐个上传下载既慢又容易被各种网站限制大小和次数。真正的问题不是“能不能压”而是有没有一套可以批量跑、参数可控、效果稳定的方案。这次我们把这几个问题一次说清先对比主流批量压缩 PDF 路线的适用场景再分别给出 Ghostscript 命令行方案、Python PyMuPDF 脚本方案和在线工具方案最后补一部分参数调整、质量评估与排查方法。看完之后你可以根据自己的使用习惯直接选一条能落地的路线开始处理文件。先给结论追求稳定和可控优先用 Ghostscript想顺手写进自动化流程就选 Python PyMuPDF只是偶尔压几个几十 MB 的临时文件在线工具完全够用。核心不是“能不能压缩”而是压缩之后清晰度是否还够用、批量任务能不能稳定跑完。1. 核心方案速览方案适用人群批量能力质量可控程度是否需要安装备注Ghostscript 命令行有命令行基础的用户强可配合 bat/shell 脚本处理整个目录高可设置压缩级别和分辨率参数需要安装 Ghostscript推荐主力方案稳定且通用Python PyMuPDF开发者、数据分析师强可直接遍历目录并输出报告中高可自定义重压缩逻辑需要安装 Python 和 PyMuPDF适合集成到业务脚本中Python pypdf/pdf2image 组合开发者中上中依赖额外转图像步骤需要安装多个依赖复杂度偏高适合特殊需求在线工具普通办公用户弱一般需要逐个上传下载低只能选预设参数无需安装适合临时轻量任务桌面版 PDF 软件普通办公用户中部分软件支持批量处理中需要安装商业软件需要授权注意版权从整个技术选型来看Ghostscript 是开源方案里最值得掌握的一个。它本身是 PDF 和 PostScript 的解释器文件压缩只是它的能力之一命令行参数稳定跨平台支持好也不存在“试用次数上限”这类限制。在线工具虽然现在体验也不错但批量任务里文件数量一多光上传下载的等待时间就够受的。2. 方案一Ghostscript 命令行批量压缩Ghostscript简称 gs是 PDF 处理领域的老牌开源工具很多桌面 PDF 软件在底层调用的其实就是它。它的优势在于参数足够丰富既可以按预设级别压缩也可以手动控制分辨率和图像质量适合对输出结果有要求的批量任务。2.1 安装 GhostscriptWindows 系统可以直接到 Ghostscript 官方网站下载安装包安装完成后把安装目录下的bin文件夹加入系统 PATH或者直接在命令行里写完整路径调用。也可以通过包管理器安装# Windows 使用 winget 安装 winget install GhostscriptLinux 和 macOS 用户用系统包管理器即可# Ubuntu / Debian sudo apt install ghostscript # CentOS / RHEL sudo yum install ghostscript # macOS brew install ghostscript验证是否安装成功gs --version能输出版本号说明安装正常。Windows 下如果安装后提示找不到命令优先检查 PATH 环境变量或者确认安装包架构是否和系统一致。2.2 Ghostscript 压缩命令解析Ghostscript 压缩 PDF 的核心命令格式如下gs -sDEVICEpdfwrite -dCompatibilityLevel1.4 -dPDFSETTINGS/ebook \ -dNOPAUSE -dBATCH -sOutputFilecompressed.pdf input.pdf参数说明参数作用-sDEVICEpdfwrite指定输出设备为 PDF 写入器是压缩 PDF 的核心参数-dCompatibilityLevel1.4设置输出 PDF 版本兼容级别1.4 对应 Adobe Acrobat 5 及以上通用性最好-dPDFSETTINGS/ebook预设压缩级别/screen体积最小画质最差/ebook中等/printer质量较高-dNOPAUSE处理过程中不暂停-dBATCH处理结束后自动退出-sOutputFilecompressed.pdf指定输出文件名input.pdf输入文件路径补充两个常用参数如果 PDF 里主要是扫描图片可以追加-dJPEGQ80调整 JPEG 图像质量-r72或-r150可以手动指定输出分辨率单位是 DPI。分辨率设得越低体积越小同时清晰度会下降具体网点点需要根据使用场景权衡。2.3 Windows 批量压缩脚本下面是一个 Windows 批处理脚本可以一次性压缩某个文件夹下所有 PDF并把压缩后的文件输出到output目录echo off setlocal enabledelayedexpansion set INPUT_DIR.\input set OUTPUT_DIR.\output set GS_PATHgs if not exist %OUTPUT_DIR% mkdir %OUTPUT_DIR% for %%f in (%INPUT_DIR%\*.pdf) do ( echo Processing: %%f %GS_PATH% -sDEVICEpdfwrite -dCompatibilityLevel1.4 -dPDFSETTINGS/ebook -dNOPAUSE -dBATCH -sOutputFile%OUTPUT_DIR%\%%~nf_compressed.pdf %%f if !errorlevel! 0 ( echo OK: %%~nf ) else ( echo FAILED: %%~nf ) ) echo Batch compression finished. pause使用时把INPUT_DIR和OUTPUT_DIR换成实际路径GS_PATH如果没加入系统 PATH就写 Ghostscript 安装目录下的完整路径例如set GS_PATHC:\Program Files\gs\gs10.03.0\bin\gs.exe这个脚本会逐文件处理每个文件生成独立的压缩结果并在控制台输出成功或失败状态。实际批量运行前先拿一个试水文件跑一遍。2.4 Linux / macOS 批量压缩脚本Linux 或 macOS 下用 bash 脚本即可#!/bin/bash INPUT_DIR./input OUTPUT_DIR./output mkdir -p $OUTPUT_DIR for f in $INPUT_DIR/*.pdf; do [ -e $f ] || continue base$(basename $f) name${base%.pdf} echo Processing: $base if gs -sDEVICEpdfwrite -dCompatibilityLevel1.4 -dPDFSETTINGS/ebook \ -dNOPAUSE -dBATCH -sOutputFile$OUTPUT_DIR/${name}_compressed.pdf $f; then echo OK: $base else echo FAILED: $base fi done保存为compress_pdf.sh加上执行权限后运行chmod x compress_pdf.sh ./compress_pdf.sh[ -e $f ] || continue这行是为了避免目录里没有 PDF 文件时脚本把字面量*.pdf也当作文件处理。3. 方案二Python PyMuPDF 批量压缩如果你平时写 Python 脚本或者希望把压缩逻辑集成进自己的业务系统里PyMuPDF导入名 fitz是比命令行更灵活的选择。它可以直接打开 PDF、读取页面数量、遍历图像对象然后把处理结果重新保存为新的 PDF 文件。3.1 安装 PyMuPDFpip install pymupdf安装后可以在 Python 里确认版本import fitz print(fitz.__doc__)PyMuPDF 目前支持 Windows、Linux 和 macOS 的主流 Python 版本。注意它的开源许可是 AGPL如果用在商业闭源软件里需要评估许可影响这点后面专门提醒。3.2 基础压缩逻辑PyMuPDF 提供一种相对直接的压缩方式打开 PDF逐页提取内容再保存到一个新的输出文件。保存时通过垃圾回收参数和压缩参数来控制体积。下面是一个最简版本import fitz def compress_pdf(input_path, output_path, garbage3, deflateTrue): doc fitz.open(input_path) # garbage3 表示最激进的清理方式回收无用对象 doc.save(output_path, garbagegarbage, deflatedeflate) doc.close() compress_pdf(input.pdf, output.pdf)这种方式的原理是把 PDF 内部冗余对象清理掉对文本类 PDF 比较有效。但如果是扫描件或图片型 PDF单纯的保存操作体积变化不够明显需要结合图像重压缩进一步处理。3.3 批量遍历目录并压缩下面是更完整的批量脚本支持遍历子目录、输出压缩报告并且过滤掉已经处理过的文件import fitz from pathlib import Path INPUT_ROOT Path(./input) OUTPUT_ROOT Path(./output) OUTPUT_ROOT.mkdir(parentsTrue, exist_okTrue) results [] for pdf_path in INPUT_ROOT.rglob(*.pdf): output_path OUTPUT_ROOT / pdf_path.name if output_path.exists(): print(f跳过已存在文件: {output_path.name}) continue original_size pdf_path.stat().st_size try: doc fitz.open(pdf_path) page_count len(doc) doc.save(output_path, garbage3, deflateTrue) doc.close() compressed_size output_path.stat().st_size ratio (1 - compressed_size / original_size) * 100 results.append({ file: pdf_path.name, pages: page_count, original_mb: round(original_size / 1024 / 1024, 2), compressed_mb: round(compressed_size / 1024 / 1024, 2), ratio: round(ratio, 1) }) print(fOK: {pdf_path.name} | 原大小 {original_size / 1024 / 1024:.2f} MB | f压缩后 {compressed_size / 1024 / 1024:.2f} MB | 减少 {ratio:.1f}%) except Exception as e: print(f失败: {pdf_path.name} | 错误: {e}) results.append({file: pdf_path.name, error: str(e)}) print(\n 批量压缩完成 ) for item in results: print(item)这段脚本的优点是每一步都有输出批量任务里哪份文件成功、哪份失败一目了然。实际项目里可以在results基础上增加 CSV 或 Excel 导出方便归档审计。3.4 图像型 PDF 的深度压缩PyMuPDF 做图像型 PDF 压缩时可以先提取页面图像缩放到合适尺寸并降低 JPEG 质量再替换回页面。常见做法是把 PDF 页面转成 pixmap经过缩放后另存为新图再嵌入新 PDF。这种方式适合扫描件但需要注意文字会变成图像一部分后期无法再选中复制。给出一个可运行的图像压缩版示例import fitz def compress_by_image(input_path, output_path, zoom1.2, jpg_quality70): doc fitz.open(input_path) new_doc fitz.open() for page in doc: # 渲染当前页面为图像 pix page.get_pixmap(matrixfitz.Matrix(zoom, zoom)) # 新建同尺寸页面 new_page new_doc.new_page(widthpage.rect.width, heightpage.rect.height) # 将渲染图像写入新页面 new_page.insert_image(new_page.rect, pixmappix) new_doc.save(output_path, garbage3, deflateTrue) new_doc.close() doc.close()这里zoom是渲染倍率jpg_quality对应后续图像导出质量实际按需求调整。要真正控制 JPEG 质量还需要先把 pixmap 导出为 JPEG 文件再判断大小具体可以用 PyMuPDF 的pix.tobytes(jpeg, jpg_quality70)完成。图像方式压缩率通常高于纯重存方式但处理时间更长大文件多页时要注意内存占用。3.5 批量监听文件夹的自动化方案如果希望做到“文件丢进文件夹就自动压缩”可以把上面的脚本包装成 watchdog 监听任务。安装watchdogpip install watchdog然后写一个监听脚本监控指定目录新增的 PDF 文件自动调用压缩函数。这种方式适合企业内部文件系统里的自动归档流程原始文件可以移动到done子目录避免重复处理。import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler from pathlib import Path class PdfHandler(FileSystemEventHandler): def on_created(self, event): if event.is_directory: return path Path(event.src_path) if path.suffix.lower() .pdf: # 调用前面定义的 compress_pdf pass observer Observer() observer.schedule(PdfHandler(), ./watch) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()关键点在于监听目录和处理目录要分开否则压缩后新文件出现在同目录会再次触发事件造成死循环。4. 方案三在线工具与桌面软件在线工具适合临时处理单份文件优势是零安装、操作直观劣势是上传下载受网络影响部分网站对文件大小和数量有限制涉及敏感资料时也不建议上传到第三方服务器。常用处理方式搜索“PDF 压缩”相关在线服务选择站点后上传 PDF选择压缩级别等待处理后下载结果。在线工具给出的“压缩率”通常只是一个估算值最终结果需要自己下载后对比清晰度。如果文件包含个人隐私或商业保密信息请先评估上传风险或者改用本地方案。桌面版 PDF 软件则适合办公场景部分商业软件支持批量压缩。如果已经有此类软件授权可以在软件内选择“批量优化”、“批量缩小文件”等入口完成处理。桌面软件和在线工具相同的问题是无法完全控制底层压缩算法对某些混合内容 PDF 的处理效果不稳定。从批量和可控角度衡量在线工具和桌面软件都不是首选。真正能反复使用、可进自动化的方案还是集中在命令行和脚本工具上。5. 批量压缩前的准备与文件管理5.1 目录规划建议批量处理 PDF 时强烈建议把输入、输出、临时目录分开project/ ├── input/ # 存放原始 PDF ├── output/ # 存放压缩后的 PDF ├── backup/ # 原始文件的备份可选 └── logs/ # 处理日志或导出报告输出文件名建议保留原文件名再增加_compressed后缀避免覆盖原始文件。后续如果要对比压缩前后的效果也方便识别。5.2 备份策略压缩过程有极小概率损坏文件尤其是来源复杂、结构异常的 PDF。批量压缩前应该先备份原文件。最简单的方式是把input文件夹整体复制一份到backup。如果空间有限也可以把原始 PDF 先打包成 zip 存放在本地。5.3 小批量试运行不要直接拿全部几百个文件跑批。正确顺序是挑 2 到 3 个文件做测试。确认输出质量符合要求。对比压缩前后大小变化。确认没有敏感信息泄漏到输出 PDF。再放行整个目录的批量任务。6. 压缩效果评估与参数选择PDF 压缩的难点在于体积与质量永远需要平衡。评估结果时可以从三个维度观察维度观察方式判断标准文件大小查看输出文件体积是否达到预期压缩比例清晰度放大页面的文字和图片边缘是否明显模糊、出现锯齿或色块可用性打开输出文件并搜索文字内容文本是否可复制、书签是否保留、页面顺序是否正确如果压缩后文字出现乱码、页面排版错乱说明参数压缩过狠需要调低压缩级别。比如从/screen改成/ebook或将图像质量从 70 提高到 85。参数选择参考表使用场景推荐参数说明网页预览、移动端阅读/screen或-r72体积最优先画质要求低普通文档存储、邮件发送/ebook或-r150通用选择可读性好正式打印、归档/printer或-r300清晰度优先压缩幅度有限处理带大批量图片的 PDF 时扫描件通常有较大压缩空间因为原图往往存在冗余信息而由程序直接导出的文本型 PDF压缩后体积变化有限这属于正常现象不是说压缩失败了。7. 常见问题与排查方法批量压缩 PDF 时最常遇到的问题集中在依赖缺失、文件损坏、输出质量异常三类。下面用表格说明。问题现象可能原因排查方式解决方案提示gs不是内部或外部命令Ghostscript 未安装或未加入 PATH运行gs --version如果提示不存在则未安装重新安装 Ghostscript或使用完整路径调用PyMuPDF 导入报错未安装依赖或 Python 版本不兼容pip list查看 pymupdf 是否安装升级 pip 后重新安装pip install --upgrade pymupdf输出 PDF 体积反而变大原文件已经过优化或使用了过高参数对比同一文件在不同参数下的输出大小改用/screen级别或检查原 PDF 是否包含大量已压缩图片压缩后文字模糊分辨率设置过低放大页面检查清晰度提高分辨率和质量参数如-r150、/ebook以上级别批量脚本处理到某个文件卡住文件结构损坏或存在超长路径单独处理该文件查看报错信息先将该文件用其他工具修复或从批量目录中移出输出文件无法打开参数设置不兼容或内存不足查看命令行错误日志降低并发数量逐文件运行检查临时磁盘空间在线工具处理速度极慢文件较大或网络带宽受限观察上传速度和网站排队情况改用本地 Ghostscript 或脚本方案批量处理生成的日志乱码Windows 控制台编码与脚本字符集不一致检查 bat 文件编码格式bat 文件保存为 ANSI 编码或使用 UTF-8 并设置chcp 65001批量脚本里出现单文件失败时不要让整个任务中断。建议为脚本增加错误收集机制失败的路径单独记录到failures.txt最后统一复查原因。# 在脚本里记录失败项示例Linux/macOS if ! gs -sDEVICEpdfwrite -dPDFSETTINGS/ebook -dNOPAUSE -dBATCH \ -sOutputFile$output_file $input_file; then echo $input_file failures.txt fi8. 最佳实践与合规提醒8.1 工程化处理建议第一次批量处理时优先用 3 到 5 个文件验证整套流程再跑全量。保留一套最小的可运行命令后续换机器只要调整路径和版本号即可。日志和输出报告是排查批量任务的基础不要只靠肉眼确认。对已压缩完成的文件可以定期抽查几个确认页面数、文件尺寸和打开正常。如果原始 PDF 涉及个人隐私、商业机密或版权内容不要使用在线工具上传优先选择本地方案。8.2 版权、隐私和安全边界处理 PDF 时要注意文件的来源。压缩别人发来的文件最好先确认你是否拥有处理该文件的权利对外发布或商用压缩后的 PDF要保证原始内容不存在版权争议。PyMuPDF 采用 AGPL 许可协议开源项目集成时通常没有问题但作为闭源商业产品分发时需要额外评估开源许可的约束。这也提醒一个细节选技术方案时要先看许可证再看功能。处理含人脸信息或隐私数据的扫描件时应提前告知相关方并获得授权。批量脚本如果部署在共享目录或服务器上注意限制目录的访问范围避免未授权用户将文件带入处理队列。8.3 结果复核习惯压缩完成后不要直接删除原始文件。正确流程是压缩 → 抽查质量 → 确认可用 → 备份原文件 → 归档压缩结果。直接销毁原文件存在不可逆风险特别是遇到压缩异常时连恢复的余地都没有。9. 总结与下一步批量压缩 PDF 的方案已经全部走了一遍。最值得优先验证的是 Ghostscript 命令行方案安装一个开源工具用一段 bat 或 shell 脚本就能处理整个目录的 PDF压缩级别、分辨率、图像质量都能自己控制。如果你平时写 Python则可以直接把 PyMuPDF 版本的脚本接进文件自动化流程效果立竿见影。最容易踩的坑有三个一是压缩参数设置过狠导致文字模糊二是输出文件名覆盖原始文件三是批处理某个异常 PDF 时脚本中断。把这三点提前规避掉整套流程基本可以稳定运行。留给你的下一步动作很简单拿几份不同类型的 PDF文本型、扫描型、图文混排型各一份分别用/screen、/ebook、/printer跑一遍对比体积和清晰度找到适合自己的参数组合。再加一个建议把批处理脚本存好这类需求通常不是一次性的。