基于内容流分析的,通用 PDF 水印检测和删除方案。适用于水印在单独流的情况
( 我提需求并控制方向,Claude code 生成代码并自动测试 )
实测效果很好,水印清除彻底,pdf 表格、图片、文字都正常,没有错位。
- ✅ 自动检测:智能分析PDF结构,自动识别疑似水印的内容流
- ✅ 精确删除:只删除水印流,100%保留正文、图片、表格
- ✅ 通用性强:支持任意PDF文件,不依赖特定水印内容
- ✅ 交互式:展示样本供用户确认,避免误删
- ✅ 快速高效:处理1877页PDF仅需2-3分钟
水印通常以固定模式添加到PDF中。本工具通过分析所有页面的内容流(Content Streams),找出大小固定、重复出现的流,这些很可能就是水印。
检测策略:
- 采样分析PDF页面(默认20页)
- 统计每个流位置的大小分布
- 识别固定大小的重复流(一致性>70%)
- 可选:提取样本文本供用户确认
删除机制:
- 使用pikepdf直接操作PDF对象
- 只删除识别出的水印流
- 保留所有正文内容和图片
pip3 install pikepdf pymupdf# 1. 自动检测并删除(交互式)
python3 remove_watermark.py input.pdf -o output.pdf
# 2. 快速模式(跳过确认)
python3 remove_watermark.py input.pdf -o output.pdf --yes
# 3. 仅分析,不删除
python3 remove_watermark.py input.pdf --analyze-only
# 4. 指定水印关键词验证
python3 remove_watermark.py input.pdf -o output.pdf --keywords "公司名称" "版权信息"# 手动指定要删除的流索引(跳过自动分析)
python3 remove_watermark.py input.pdf -o output.pdf --stream-index 2
# 指定流大小范围(更精确)
python3 remove_watermark.py input.pdf -o output.pdf --stream-index 2 --size-range 3700 3800
# 增加采样页数(更准确的分析)
python3 remove_watermark.py input.pdf -o output.pdf --sample-pages 50# 分析PDF
$ python3 remove_watermark.py mpp.pdf --analyze-only
📊 分析PDF: mpp.pdf
总页数: 1877
🔍 内容流模式分析:
流位置 3:
最常见大小: 3741 bytes
一致性: 100.0% (20/20 页)
⚠️ 疑似水印流!
# 删除水印
$ python3 remove_watermark.py mpp.pdf -o mpp_clean.pdf --yes
✅ 完成!
处理页数: 1877/1877 (100.0%)
原始大小: 14.00 MB
新文件大小: 13.01 MB
减小: 1.00 MB (7.1%)python3 remove_watermark.py document.pdf -o clean.pdf \
--keywords "内部资料" "仅供参考"| 参数 | 说明 | 默认值 |
|---|---|---|
input |
输入PDF文件路径 | 必需 |
-o, --output |
输出PDF文件路径 | {input}_clean.pdf |
--analyze-only |
仅分析,不删除 | False |
--stream-index |
手动指定要删除的流索引(从0开始) | 自动检测 |
--size-range MIN MAX |
流大小范围(仅删除该范围内的流) | 无限制 |
--keywords |
水印关键词(用于验证) | 无 |
--sample-pages |
分析采样页数 | 20 |
-y, --yes |
跳过确认,自动执行 | False |
运行分析模式:
python3 remove_watermark.py your.pdf --analyze-only如果输出显示"疑似水印流",说明检测到了。
本工具的安全机制:
- 只删除固定大小的重复流(正文内容通常大小不同)
- 交互式确认(除非使用
--yes) - 自动验证图片完整性
可能的原因:
- PDF没有水印
- 水印嵌入方式特殊(不是独立流)
- 采样页数太少
解决方法:
# 增加采样页数
python3 remove_watermark.py your.pdf --analyze-only --sample-pages 50
# 或者手动指定(如果你知道是哪个流)
python3 remove_watermark.py your.pdf -o output.pdf --stream-index 2检查是否设置了--size-range。如果没有设置,工具会删除所有指定索引的流。
建议:
# 先分析,记下疑似水印流的大小(比如3741 bytes)
python3 remove_watermark.py your.pdf --analyze-only
# 然后指定大小范围(±50 bytes)
python3 remove_watermark.py your.pdf -o output.pdf \
--stream-index 2 --size-range 3690 3790核心技术:
- pikepdf:底层PDF对象操作
- PyMuPDF:文本提取和验证
- 内容流分析:统计学方法识别固定模式
关键算法:
for 每个流位置:
if 该位置在多数页面中大小相同(±50 bytes):
且一致性 > 70%:
标记为疑似水印| 方面 | 之前(文本提取) | 现在(流删除) |
|---|---|---|
| 正文 | ✅ 保留 | ✅ 保留 |
| 图片 | ❌ 丢失 | ✅ 保留 |
| 表格 | ❌ 丢失 | ✅ 保留 |
| 格式 | ❌ 丢失 | ✅ 保留 |
| 水印 | ✅ 去除 | ✅ 去除 |
| 文件大小 | 2.7 MB (纯文本) | 13.01 MB (完整PDF) |
| 处理时间 | ~1分钟 | ~2分钟 |
作者: GengXinyuan 日期: 2025-11-27 版本: 1.0
致谢:
- pikepdf: https://github.com/pikepdf/pikepdf
- PyMuPDF: https://github.com/pymupdf/PyMuPDF
- ✅ 初始版本
- ✅ 自动检测固定大小的内容流
- ✅ 智能合并相近大小(±50 bytes)
- ✅ 交互式确认
- ✅ 关键词验证
- ✅ 处理1877页大型PDF