GitHub - overflowy/make-look-scanned: 让 PDF 看起来像扫描件(通过 WASM 在命令行或浏览器中运行)

2026-06-21T04:19:24.449038

GitHub - overflowy/make-look-scanned: 让 PDF 看起来像扫描件(通过 WASM 在命令行或浏览器中运行)

一个命令行工具(CLI),它接收一个 PDF 文件并将其劣化处理,使其看起来像是打印件的物理扫描件——包括倾斜、灰度、暖色纸张色调、扫描仪颗粒、失焦、边缘阴影和 JPEG 压缩伪影。同时它也通过 WASM 在浏览器中客户端运行

example

每一页都被光栅化为图像,经过效果管线处理,然后重新组装成一个新的纯图像 PDF(原始的可选文本被移除——符合基础扫描仪的特性)。

需要 Go 和 C 工具链(go-fitz 通过 cgo 链接 MuPDF,因此二进制文件是自包含的——运行时无需安装任何东西)。

go build -o make-look-scanned .
make-look-scanned [flags] input.pdf

标志位可以出现在输入文件名之前或之后。

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
标志位 默认值 含义
-o .scanned.pdf 输出路径
--preset 来自 config.toml 的命名预设
--seed 内容哈希 随机种子(覆盖后获得新的外观)
--force false 覆盖已有的输出文件
--dpi 150 渲染分辨率
--skew 0.6 最大旋转角度(0 禁用)
--grayscale true 去饱和度(--grayscale=false 保留颜色)
--paper-tone 0.6 暖色纸张色调强度 0..1
--noise 0.08 扫描仪颗粒 0..1
--blur 0.4 失焦高斯模糊的 sigma
--edge-shadow 0.15 边框暗角 0..1
--jpeg-quality 70 JPEG 质量 1..100

每个数值参数在设为 0 时禁用该效果。

默认情况下输出是确定性的:种子由输入 PDF 的内容派生,因此同一个文件总是产生相同的扫描效果。通过 --seed N 可以获得不同的(但可重现)外观。相同的输入 + 种子会生成字节完全相同的 PDF。

$XDG_CONFIG_HOME/make-look-scanned/config.toml 中定义可重用的预设包(当 XDG_CONFIG_HOME 未设置时,回退到 ~/.make-look-scanned/config.toml)。键名与标志位名称对应,使用下划线:

[presets.medium]
skew = 1.5
paper_tone = 0.6
noise = 0.2
blur = 0.6
edge_shadow = 0.3
jpeg_quality = 45
make-look-scanned --preset medium in.pdf

优先级:内置默认值 → 选中的预设 → 显式的 CLI 标志位(标志位始终优先)。

效果管线也可以在浏览器中运行。go-fitz/MuPDF 无法编译到 wasm,因此浏览器使用 PDF.js 来光栅化页面,并将像素传递给相同的 Go 效果代码以及编译到 wasm 的汇编代码。

开发(需要网络以访问 PDF.js CDN):

./web/build.sh # 构建 web/main.wasm + wasm_exec.js
(cd web && python3 -m http.server 8080) # 然后打开 http://localhost:8080

单个自包含文件(离线可用,无需提供任何服务):

task build:web # 写入 dist/make-look-scanned.html(约 8 MB)
dist/make-look-scanned.html 将 wasm、Go 运行时胶水代码以及 PDF.js(库 + worker)以内联方式嵌入为 base64——直接在浏览器中打开。输出在视觉上与 CLI 等效,但由于 PDF.js 和 MuPDF 的光栅化方式不同,字节并非完全相同。

AGPL-3.0。CLI 静态链接了 MuPDF(通过 go-fitz),而 MuPDF 是 AGPL-3.0 许可,因此合并后的二进制文件也是 AGPL-3.0——分发时需要提供相应的源代码。浏览器构建版本不包含 MuPDF(它使用 PDF.js,Apache-2.0 许可)。

查看原文