PDF 合并与智能压缩
核心引擎:PDFBox-Android
ZenConverter 的 PDF 路线(合并、压缩、加解密、文本提取)全部基于 PDFBox-Android 这个库——Apache PDFBox 的 Android 移植版本。为什么不自己写?因为 PDF 是一个非常复杂的格式(支持矢量、栅格、文字层、表单、注释、嵌入字体……),手写一个可用的 PDF 引擎工程量巨大。
PDFBox-Android 和 Android 系统 PdfDocument/PdfRenderer 的分工:
| 引擎 | 覆盖场景 |
|---|---|
| Android PdfDocument / PdfRenderer | 图片 → PDF、PDF → 图片(栅格化) |
| PDFBox-Android | PDF 合并、PDF 压缩、PDF 加解密、PDF 文本提取 |
选择 PDFBox-Android 的好处是:它不重新栅格化 PDF。合并时把源 PDF 的页对象(矢量路径、文字层、嵌入字体)原样拷贝到新 PDF,不是先栅格化成图片再合——这样合并后的 PDF 仍然可以选中文字、矢量仍然清晰。
PDF 合并
多个 PDF 按顺序合并成一个 PDF:
- 选多个 PDF → 选"合并";
- 合并的源 PDF 顺序 = 你在应用里的选择顺序;
- 输出一个合并后的 PDF,页数 = 各源 PDF 页数之和。
已知限制
- 不保留表单:复杂 PDF 表单(可填写字段、按钮)的结构在合并过程中可能丢失——这是 PDFBox-Android 的当前限制;
- 不保留书签:源 PDF 的目录书签不会被拷贝到合并后的 PDF;
- 不保留附件:源 PDF 里嵌入的附件文件不会被拷贝;
- 元数据 best-effort:作者、标题等元数据会尽力保留,但不保证完全正确。
合并的核心承诺是保留普通文字层和矢量内容——这已经覆盖了大多数文档合并场景(报告、论文、合同合并)。
PDF 智能压缩
PDF 体积大主要有两个原因:内嵌图片分辨率太高(扫描 PDF 最常见)和冗余元数据(缩略图)。压缩就是针对这两点:
三档预设
| 档位 | 内嵌图质量 | 内嵌图最大尺寸 | 输出风格 |
|---|---|---|---|
| 高画质 | 85% JPEG 质量 | 2160 px(短边) | 画质优先 |
| 均衡 | 70% JPEG 质量 | 1440 px(短边) | 平衡 |
| 小体积 | 50% JPEG 质量 | 1080 px(短边) | 体积优先 |
压缩策略
- Downsample 内嵌图:PDF 里的栅格图(扫描页、截图)downsample 到最大短边像素;
- 重编码:downsample 后的图用 JPEG 重编码(对应档位质量);
- 剥离冗余缩略图元数据:PDF 里可能嵌有各页的缩略图(冗余存储),直接删掉;
- 不碰矢量和文字层:PDF 的矢量路径、文字层、嵌入字体保持原样——压缩不改变排版和可选文字。
效果估算
一个 50 MB 的扫描 PDF,用"小体积"档压缩后可能降到 5–10 MB,肉眼看不出明显损失(因为主要压的是扫描页内嵌的栅格图)。一个包含大量矢量图形和少量嵌入图的设计 PDF,压缩效果会很有限(因为矢量不压,只压内嵌图)。
为什么叫"智能"压缩
和很多 PDF 压缩工具不同,ZenConverter 压缩不重新栅格化整个 PDF:
- 矢量 → 保留矢量;
- 文字层 → 保留文字层;
- 只有内嵌的栅格图被 downsample + 重编码。
这样压缩后的 PDF 仍然可以选中文字、可以搜索、可以矢量放大不糊。
使用场景
| 场景 | 推荐 |
|---|---|
| 合并几个 PDF 报告成一份完整文档 | PDF 合并 |
| 扫描 PDF 太大发不出去 | PDF 压缩 + 小体积档 |
| 从 PDF 里拆出几页 + 合并成新 PDF | 先在 PDF → 图片路线里选指定页栅格化,再图片合 PDF(绕一圈但可用) |
相关页面
- PDF 密码加解密 —— PDF 加解密也走 PDFBox-Android
- PDF 提取 TXT / Markdown —— 文字提取路线
- Office OOXML 本地转 PDF —— Office 文档也能转 PDF
