PDF橡皮(PDF Eraser)
像橡皮一样,把 PDF 里的第三方水印擦干净。针对转载类文档(研报、电子书、
内部流出资料)中最常见的两种水印:
- 图片水印 — 每页重复嵌入的小横幅图(推广文字、二维码、联系方式)。
自动检测并无损删除,正文、图表、原版式完全不受影响。 - 文字水印 — 页面上重复出现的文字("DRAFT"、"仅供内部参考"等),
按关键词定位后用背景色矩形覆盖。
Quick Start
# 一条命令:自动检测并擦除图片水印
python scripts/pdf_eraser.py input.pdf
# 只看检测候选,不动文件
python scripts/pdf_eraser.py input.pdf --list
# 指定 xref 精准删除——自动检测漏检或有歧义时使用
python scripts/pdf_eraser.py input.pdf --watermark-xref 103
# 按关键词擦除文字水印
python scripts/pdf_eraser.py input.pdf --watermark-text "调研先知"
# 生成处理前后对比预览(前3页)
python scripts/pdf_eraser.py input.pdf --preview-dir /tmp/preview
Default output is <input>_cleaned.pdf; override with -o.
Workflow
- Run inspection (
--listor bare invocation) to see every image xref
with its usage count, size, and page coverage. - Auto-detection logic (already implemented in the script):
- Candidate = image appearing on ≥ 90% of pages.
- Ranked "banner" = aspect ratio ≥ 2.5 and height ≤ 400 px (typical promo
banner). Default removal only touches banner candidates; use
--all-candidatesto remove every repeated image (risky — branding
logos also repeat on every page). - Verify before trusting auto-detection. When the agent can view images,
export candidates withdoc.extract_image(xref)or use--preview-dir
and visually confirm the candidate is a watermark, not a logo/letterhead.
When in doubt, remove by explicit--watermark-xrefafter visual checks. - Confirm afterwards: re-open the output, check the watermark xref is
gone and page count/content is unchanged.
Field Notes (learned from real JPM/GS research reports)
- The same watermark image xref often appears multiple times per page
(4× in observed files) — onedelete_image(xref)call per page covers all. - Branding elements to preserve: J.P. Morgan side bar (164×2200 vertical
strip), company logos (~216×45, ~90% page coverage but NOT banner-shaped —
correctly skipped by the banner heuristic). - Full-page content images (1700×2200, one per page) must never be touched;
they appear once per page so they never become candidates. - Producer metadata like
pdf-lib+ obfuscated text streams indicate the
file was re-processed by a distribution tool — watermark is almost
certainly an added image layer in that case. - After
garbage=4save, xrefs get renumbered — verify by image dimensions
(e.g. no remaining 677×177 image), not by the old xref number.
Dependencies
- Python 3.9+ with PyMuPDF (
pip install pymupdf).
No other dependencies. Runs offline — nothing is uploaded anywhere.