乐于分享
好东西不私藏

一行命令把 PDF 伪装成扫描件:开源工具 make-look-scanned 的妙用

一行命令把 PDF 伪装成扫描件:开源工具 make-look-scanned 的妙用

PDF 扫描质感这种东西,听起来是设计师的活儿。

但开源社区里偏偏有人用两百行 Go 代码搞定——而且做得比 Adobe Acrobat 那个藏了十层的”扫描优化”按钮还地道。make-look-scanned(GitHub: overflowy/make-look-scanned)就是这样一个工具:给你一个干干净净的数字 PDF,一行命令下去,出来的是歪歪斜斜、灰度偏黄、边角发暗、带着扫描颗粒的”复印稿”。

最神奇的是,输出是确定性的。同一个 PDF 不管跑多少遍,字节级一致。这点在”扫描”这个领域里几乎没人做到——因为通常的随机噪声会让每次结果都不一样。


它到底做了啥

CLI 用法极简:

make-look-scanned in.pdf            # 输出 in.scanned.pdf make-look-scanned in.pdf -o out.pdf make-look-scanned in.pdf --noise 0.4 --skew 2.5 --jpeg-quality 30

所有效果都是参数化的——

Flag
默认值
干啥
--skew
0.6
页面歪斜角度
--grayscale
true
灰度化
--paper-tone
0.6
米黄纸调
--noise
0.08
扫描颗粒
--blur
0.4
高斯失焦
--edge-shadow
0.15
边缘暗角
--jpeg-quality
70
JPEG 压缩瑕疵
--seed
内容 hash
随机种子(决定颗粒分布)

每个数值调到 0 那个效果就关掉。换句话说,你可以把歪斜关了但保留米黄纸调,也可以全关掉只留 JPEG 瑕疵

输出 PDF 是图-only——原文的可选文本没了。这点很”诚实”:真扫描仪本来也就这样。


技术上值得说的三件事

1. 静态链接 MuPDF,没运行时依赖。

go build 出二进制就完事了,不要求用户装什么 poppler、imagemagick、ghostscript。原因是 go-fitz 把 MuPDF 用 cgo 链进去了——代价是编译需要 C 工具链,但用户用的时候啥都不缺。

2. WASM 版能跑在浏览器里。

MuPDF 没法编 wasm,所以浏览器版改用 PDF.js 栅格化页面,但效果处理用同一份 Go 代码编译成的 wasm。换句话说,CLI 和浏览器共享同一套算法。

更进一步:task build:web 能生成一个 8MB 的单 HTML 文件,里面把 wasm、Go runtime glue、PDF.js 库和 worker 都 base64 编码进去——离线可用,丢任何地方双击就开

3. 确定性输出。

种子从 PDF 内容 hash 派生。同一份输入 + 同一份种子 = 字节相同的输出。这对审计、测试、合规场景非常关键——你可以反复重跑同一份合同,永远得到同一份”扫描件”。


谁会用这种东西

  • 提交纸质材料
    很多机构只认”看起来扫过的”PDF,比如一些只接受扫描件归档的内部 OA、纸质化流程的最后一公里;
  • 设计/原型稿脱敏
    把可复制的设计稿转成图-only,避免内容被复制粘贴;
  • AI 训练数据
    把数字文档伪装成扫描件,能破坏 OCR-first 的抓取管道;
  • 个人恶搞
    把干净的论文改成”手抄错字”的扫描感,发给朋友笑。

这里要插一句:把扫描质感当”防 OCR 工具”是误用——专业 OCR 引擎对扫描噪声有专门训练。make-look-scanned 的真正价值是视觉质感,不是对抗性脱敏。


许可证与生态

AGPL-3.0。原因是静态链了 MuPDF(也是 AGPL-3.0)——分发二进制需要附上对应源码。浏览器版本不含 MuPDF(用 Apache-2.0 的 PDF.js),所以 web build 的许可证约束会轻一些。

GitHub 仓库 690+ stars。开发者 overflowy 没有大动作社交媒体宣传,纯靠自然流量。这反倒让它更有”独立工具”的味道。


↓ 点击阅读原文,查看相关链接 ↓