Show HN: Make PDFs look scanned (CLI or in the browser via WASM)

overflowy1 pts0 comments

GitHub - overflowy/make-look-scanned: Make PDFs look scanned · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

overflowy

make-look-scanned

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>6 Commits<br>6 Commits

.github/workflows

.github/workflows

cmd/wasm

cmd/wasm

internal

internal

web

web

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

Taskfile.yml

Taskfile.yml

go.mod

go.mod

go.sum

go.sum

main.go

main.go

View all files

Repository files navigation

make-look-scanned

A CLI that takes a PDF and degrades it to look like a physical scan of a<br>printout — skew, grayscale, warm paper tone, scanner grain, defocus, edge<br>shadow, and JPEG compression artifacts. Also runs client-side in the browser via WASM.

Each page is rasterized to an image, run through the effect pipeline, and<br>reassembled into a new image-only PDF (the original selectable text is<br>gone — faithful to a basic scanner).

Build

Requires Go and a C toolchain (go-fitz links MuPDF via cgo, so the binary is<br>self-contained — nothing to install at runtime).

go build -o make-look-scanned .

Usage

make-look-scanned [flags] input.pdf

Flags may appear before or after the input filename.

in.scanned.pdf<br>make-look-scanned in.pdf -o out.pdf<br>make-look-scanned in.pdf --noise 0.4 --skew 2.5 --jpeg-quality 30">make-look-scanned in.pdf # -> in.scanned.pdf<br>make-look-scanned in.pdf -o out.pdf<br>make-look-scanned in.pdf --noise 0.4 --skew 2.5 --jpeg-quality 30

Flags

Flag<br>Default<br>Meaning

-o<br>.scanned.pdf<br>output path

--preset<br>named preset from config.toml

--seed<br>content hash<br>random seed (override for a new look)

--force<br>false<br>overwrite an existing output file

--dpi<br>150<br>render resolution

--skew<br>0.6<br>max rotation degrees (0 disables)

--grayscale<br>true<br>desaturate (--grayscale=false keeps color)

--paper-tone<br>0.6<br>warm paper tint strength 0..1

--noise<br>0.08<br>scanner grain 0..1

--blur<br>0.4<br>defocus gaussian sigma

--edge-shadow<br>0.15<br>border vignette 0..1

--jpeg-quality<br>70<br>JPEG quality 1..100

Each numeric knob disables its effect at 0.

Determinism

Output is deterministic by default : the seed is derived from the input<br>PDF's content, so the same file always produces the same scan. Pass --seed N<br>for a different (but reproducible) look. Same input + seed yields a<br>byte-identical PDF.

Presets

Define reusable bundles in<br>$XDG_CONFIG_HOME/make-look-scanned/config.toml (falls back to<br>~/.make-look-scanned/config.toml when XDG_CONFIG_HOME is unset). Keys<br>mirror the flag names with underscores:

[presets.medium]<br>skew = 1.5<br>paper_tone = 0.6<br>noise = 0.2<br>blur = 0.6<br>edge_shadow = 0.3<br>jpeg_quality = 45

make-look-scanned --preset medium in.pdf

Precedence: built-in defaults → selected preset → explicit CLI flags (flags<br>always win).

Browser (WebAssembly)

The effect pipeline also runs in the browser. go-fitz/MuPDF can't compile to<br>wasm, so the browser uses PDF.js to rasterize pages and hands the pixels to<br>the same Go effects + assembly code compiled to wasm.

Dev (needs network for the PDF.js CDN):

./web/build.sh # builds web/main.wasm + wasm_exec.js<br>(cd web && python3 -m http.server 8080) # then open http://localhost:8080

Single self-contained file (works offline, nothing to serve):

task build:web # writes dist/make-look-scanned.html (~8 MB)

dist/make-look-scanned.html inlines the wasm, Go's runtime glue, and PDF.js<br>(library + worker) as base64 — open it directly in a browser. Output is<br>visually equivalent to the CLI but not byte-identical, since PDF.js and MuPDF<br>rasterize differently.

License

AGPL-3.0. The CLI statically links MuPDF (via go-fitz), which is<br>AGPL-3.0, so the combined binary is AGPL-3.0 — distributing it requires offering<br>the corresponding source. The browser build does not include MuPDF (it uses<br>PDF.js, Apache-2.0).

About

Make PDFs look scanned

overflowy.github.io/make-look-scanned/

Topics

go

pdf

wasm

scan

Resources

Readme

License

AGPL-3.0 license

Uh oh!

There was an error while loading. Please reload this...

look scanned make wasm browser github

Related Articles