PDF 隐私涂黑

真删内容流里的文字 · 输出后自动复检 · 本地处理,文件不上传

先把最要紧的一句话放在前面:在 PDF 上画个黑框,不等于删掉了下面的字。 微信截图打码、Adobe 的「遮盖」审阅标记、各种在线打码工具,绝大多数做完之后 你仍然可以框选那段黑块、Ctrl+C、粘到记事本里,字就在那儿。 把文件转成文本、转成 Word,一样原样吐出来。

这不只是「工具不够好」,而是一类真实发生过的泄密事故:对外发布的文件里做了「遮挡」, 接收方全选复制就看到了没打码的原文。遮挡是视觉层的事,删除是文件结构层的事。

上传 PDF

点击选择,或把 PDF 拖进来
文件在你自己的浏览器里处理,不会被上传 · 支持多页,逐页框选

怎么做的:把文字绘制指令从内容流里摘掉

PDF 的一页正文,本质是一串「画字」指令。一个典型的中文句子在文件里长这样(已解压):

% 定位到某处,开始文本块
BT
  /F4 20 Tf                      % 用 F4 字体,20 号
  1 0 0 -1 48 88 Tm             % 文本矩阵:把坐标原点挪到 (48,88)
  <EB> Tj                        % 画第一个字
  19.99 0 Td <10> Tj             % 右移 19.99,画第二个字
  19.99 0 Td <35> Tj             % ← 这一句落在你的框里
ET

黑框工具的做法是:在这段指令后面再加一条「画个实心矩形」。 原指令还在,所以文字层还在。

这个工具的做法是:先把流解压,逐条指令算出它画出来的字在页面上的实际包围盒 (要连 cm 变换矩阵、Tm 文本矩阵、字号、字宽、字距 Tc/Tw、 水平缩放 Tz、上标 Ts 一起算,光看坐标是不够的), 凡是包围盒和你框选区域相交的,把那条指令整段从流里剪掉, 重新压缩写回,最后把旧的流对象整个删掉。

最后那一步很多人会漏。只把页面指向新流、不删旧流,旧对象仍然躺在文件里, 只是没人引用它 —— 用 strings file.pdf 之类的办法照样能捞出来。 本工具会检查该流是否被别的页共享引用,只删「仅此页使用」的,避免把别的页弄坏。

凭什么让你相信「真删了」:独立复检

这页有个别的工具没有的环节。处理完之后,工具把输出的文件当成一个陌生文件重新打开, 用 pdf.js(Mozilla 的 PDF 引擎,和我上面算几何的那套代码完全独立) 重新提取文字层,把每个文字条目换算成坐标,再看有没有落在你框选的区域里。

结果直接打在页面上:

用两套不同的引擎互为对照,是因为「我自己算的那套」如果算错了,自己验自己是验不出来的。 这一点我觉得比多画十个功能都重要。

它做不到什么(先说清楚,省得你白试)

内容能不能处理说明
正文里的文字 能,真删 本工具的主功能。删除后文本层提取不到,不是被盖住。
文档属性 / 作者 能 默认勾选一并清掉。否则正文涂了、属性里还写着作者名。
扫描件、截图里的字 不能 那是图像像素,不是文字对象。黑块能盖住它,但像素还在文件里, 把图导出来就看见了。工具检测到该页有图像时会明确警告你。 扫描件要彻底处理,只能重新截图/重印后再遮挡。
表单域里的填写内容 不能 那是注释对象(AcroForm),不在页面内容流上,本工具不碰。填过的表单请先在阅读器里「展平」。
已数字签名的文件 不能 改任何一个字节都会让签名失效。这是签名的定义,不是工具的缺陷 —— 正确顺序是先涂黑,再签名。
有打开密码的文件 不能 本工具不猜密码、不上传。请先在本地解密再来。

自动识别:只认四种号码,别指望它认名字

「自动识别号码」会扫全页文字,按格式找出手机号、18 位身份证号、16–19 位银行卡号、邮箱, 自动加上框选。全角数字会先归一化再匹配,所以「138…」这种也能认。

但它认不出姓名、地址、公司名、病情描述——那些没有固定格式,靠正则猜只会又漏又错。 自动识别只是省掉重复拖框的手,标出来之后仍然要你自己逐个人工核对。 页面在自动标记后会这么提醒你,不会让你以为点一下就够了。

典型会用到的场合

关于「文件不上传」

解析、改写、复检全部在你浏览器里跑。用到的两个库都托管在本站 (/js/pdf-lib.min.js、/js/pdf.min.js),不走第三方 CDN, 所以连「有人打开过这个页面」都不会外泄。页面加载完之后断网也照常能用。

这不是洁癖。会需要涂黑的文件,共同点正是泄露了没法撤回: 身份证、合同、病历、报价单。把这种文件上传到一个不知道谁在运营的服务器上, 本身的风险就比你要涂掉的那行字更大。