从遮盖红色元素到彻底移除PDF对象:一个PDF去印章脚本的技术演进历程

作者:袖梨 2026-05-22

PDF文档中的红色印章常影响可读性,本文分享一种通过分析PDF结构实现高效去印章的技术方案。

从“涂掉红色”到“删除 PDF 对象”:一次 PDF 去印章脚本改造实践

.
├── input
│   ├── 含印章文档1.pdf
│   └── 含有印章文档.pdf
├── output
│   ├── 含印章文档1.pdf
│   └── 含有印章文档.pdf
└── remove_red_seal.py

最初采用的方案是将PDF页面转换为图片后,使用OpenCV的inpaint功能进行图像修复。这种方法虽然可行,但存在明显缺陷:它破坏了PDF原有的文档结构,导致文字可选中性丧失,且处理效果不够理想。

原方案的问题

原始方案的核心代码如下:

def remove_stamp_from_image(img):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_red = np.array([0, 43, 46])
    upper_red = np.array([10, 255, 255])
    mask = cv2.inRange(hsv, lower_red, upper_red)
    result = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
    return result

该方法存在以下主要问题:

  1. PDF文字会变成不可选的图片
  2. 页面清晰度受渲染DPI限制
  3. 印章边缘半透明像素可能残留
  4. 无法真正恢复被覆盖的内容
  5. 容易误伤红色正文或批注

关键发现:印章是独立图片对象

分析发现,测试文档中的印章实际上是独立的图片对象,而非与正文融合的图像。使用pdfplumber检查对象数量显示:

input
含印章文档1.pdf    pages=1  chars=451  images=1
含有印章文档.pdf    pages=1  chars=562  images=1output
含印章文档1.pdf    pages=1  chars=451  images=0
含有印章文档.pdf    pages=1  chars=562  images=0

在PDF内容流中,印章通常以类似以下形式出现:

q
260 0 0 360 168 241 cm
/Im1 Do
Q

新方案:优先对象层删除,后备内容流重写

改进后的方案采用两层策略:

  1. 优先使用PyMuPDF直接删除图片对象
  2. 后备方案解析PDF内容流进行修改

核心流程如下:

for page in doc:
    for image in page.get_images(full=True):
        xref = image[0]
        pix = fitz.Pixmap(doc, xref)
        if _looks_like_red_stamp(bgr):
            page.delete_image(xref)

红章识别:不是只看红色像素

为避免误删,识别算法采用了多条件判断:

return (
    (r16 > 70)
    & (r16 > g16 + 18)
    & (r16 > b16 + 18)
    & (r16 > (g16 * 1.12))
    & (r16 > (b16 * 1.12))
)

为什么输出质量更好

新方案的优势在于:

  1. 保持文字为矢量格式
  2. 文件体积更小
  3. 无涂抹痕迹
  4. 不会误修正文
  5. 处理效果更干净

扫描件怎么办

对于印章已与扫描图融合的情况,需采用图像处理流程:

  1. 高DPI渲染页面
  2. 提取红色区域
  3. 进行形态学处理
  4. 使用inpaint修复
  5. 保护文字和表格线

建议的处理优先级为:

PDF 对象层删除 -> 内容流修补 -> 图像级修复 -> 人工复核

本文介绍的技术方案通过分析PDF结构实现了高效去印章,既保留了文档质量又提升了处理效率。对于电子文档,优先删除印章对象是最佳选择,而扫描件则需结合图像处理技术。


python包依赖:

pip install pymupdf opencv-python numpy pillow

源码:

#!/usr/bin/env python3
"""
Remove red seal / stamp images from PDFs in input/ and write clean PDFs to output/.Preferred path:
  - PyMuPDF removes the stamp image object from the PDF page, preserving vector text.Fallback path:
  - For simple PDFs like the samples in this project, patch the PDF content stream
    incrementally and remove only the drawing commands for red image XObjects.Optional install for the preferred path:
  pip install pymupdf opencv-python numpy pillow
"""from __future__ import annotationsimport os
import re
import shutil
import zlib
from dataclasses import dataclass
from pathlib import Pathimport cv2
import numpy as np
INPUT_FOLDER = Path("./input")
OUTPUT_FOLDER = Path("./output")
@dataclass(frozen=True)
class PdfObject:
    number: 

相关文章

精彩推荐