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所有效果都是参数化的——
--skew | ||
--grayscale | ||
--paper-tone | ||
--noise | ||
--blur | ||
--edge-shadow | ||
--jpeg-quality | ||
--seed |
每个数值调到 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 没有大动作社交媒体宣传,纯靠自然流量。这反倒让它更有”独立工具”的味道。


↓ 点击阅读原文,查看相关链接 ↓
夜雨聆风