乐于分享
好东西不私藏

PDF去水印不求人:一个Python脚本搞定图片水印+文字水印

PDF去水印不求人:一个Python脚本搞定图片水印+文字水印

PDF去水印不求人:一个Python脚本搞定图片水印+文字水印

老师们平时拿到各种试卷、答案PDF,很多都带着大大的水印——图片水印挡内容,文字水印铺满整页,打印出来乱糟糟。

今天分享一个方法:用 Python + PyMuPDF 一键去除 PDF 中的图片水印和文字水印,原文件内容完全不受影响。

准备工作

安装 PyMuPDF:

pip install pymupdf

就这一个依赖,没有其他的了。

水印有哪几种?

PDF 中的水印大致分三类:

  1. 图片水印:整页覆盖一张半透明图片,3414×617 的大图横跨全页
  2. 文字水印:"关注×××公众号、抖音、小红书获取最新消息"这类文字,用小字体、浅灰色铺满页面
  3. 混合水印:图片+文字同时存在,有的还有多层重叠

最难搞的是图片水印,因为它是一个 Form XObject 嵌入在 PDF 内容流中,覆盖在原文上面。

核心思路

文字水印:Redaction(遮涂)

PyMuPDF 提供了 add_redact_annot + apply_redactions 方法,可以精确地"擦除"指定区域的内容:

# 搜索水印文字位置instances = page.search_for("关注湖北升学通")for rect in instances:# 扩大区域覆盖完整水印行    r = fitz.Rect(rect.x0 - 5, rect.y0 - 3, rect.x1 + 200, rect.y1 + 10)    page.add_redact_annot(r, fill=None)  # fill=None 表示不填充颜色page.apply_redactions()  # 应用擦除

关键点:fill=None 表示擦除后不填充任何颜色,保持页面底色不变。

图片水印:删除内容流引用

图片水印本质上是在页面内容流中放了一个 XObject 引用。我们需要:

  1. 找到水印图片的 xref:用 page.get_images() 找出大尺寸图片
  2. 找到中间 Form XObject:水印图片通常被包装在一个 Form XObject 中
  3. 删除内容流中的绘制命令:移除 /KSPX1 Do 这类 Do 命令
  4. 删除资源字典中的映射:移除 /KSPX1 79 0 R 这类映射
  5. 删除水印对象本身:用 doc._deleteObject() 清理
# 删除内容流中的水印绘制命令content = content.replace("/KSPX1 Do""")# 删除资源字典中的映射import repattern = r"/KSPX1\s+\d+\s+0\s+R"content = re.sub(pattern, "", content)# 删除水印图片对象doc._deleteObject(79)

完整脚本

import fitz, re, globpdf_path = "你的文件.pdf"out_path = "去水印后.pdf"doc = fitz.open(pdf_path)# 水印关键词(根据实际情况修改)watermark_keywords = ["关注湖北升学通""公众号""抖音","小红书""获取最新消息""获取最新",]for page_num inrange(len(doc)):    page = doc[page_num]# 多轮删除文字水印for _ inrange(5):for keyword in watermark_keywords:            instances = page.search_for(keyword)for rect in instances:                r = fitz.Rect(                    rect.x0 - 5, rect.y0 - 3,                    rect.x1 + 200, rect.y1 + 10                )                page.add_redact_annot(r, fill=None)        page.apply_redactions()    page.clean_contents()doc.save(out_path, garbage=4, deflate=True)doc.close()print("完成!")

几个踩过的坑

坑1:水印文字被拆成多个字形

PDF 为了防提取,经常把"关注湖北升学通"拆成单独的字形(glyph)分别渲染。所以搜索"关注湖北升学通"只能找到前几个字的位置,后面的"公众号、抖音、小红书"漏掉了。

解决:把所有可能的片段都列为关键词,多轮搜索删除。

坑2:多层重叠水印

有的 PDF 同一个水印铺了好几层,删除一层还有另一层。

解决:多轮循环删除(5轮),每轮 apply_redactions() 后重新搜索。

坑3:图片水印是 Form XObject

水印图片不是直接放在页面里,而是包装在一个 Form XObject 中,页面通过 /Name Do 命令引用它。直接删除图片对象会导致"cannot find XObject resource"错误。

解决:必须同时删除资源字典映射、内容流 Do 命令、以及水印对象本身,顺序不能错。

效果对比

去水印前:整页铺满半透明水印图片 + 灰色文字水印,严重影响阅读和打印。

去水印后:所有水印痕迹消失,试卷原文、公式、图片全部完好无损。

适用场景

  • 各地联考、统考的试卷和答案 PDF
  • 带有机构宣传水印的复习资料
  • 需要二次排版或打印的 PDF 文件

只需要把 watermark_keywords 列表替换成你文件中实际的水印文字,就能适配不同来源的 PDF。


如果这篇文章对你有帮助,欢迎分享给需要的同事!