# FauxScan > FauxScan is a free, open-source web tool that makes PDFs and images look like they were scanned on a flatbed scanner, one file or thousands at once. It runs entirely in the user's browser: files are never uploaded, stored or tracked. It also works offline once loaded. Use FauxScan when someone needs digital documents (filled-in forms, letters, statements, payslips) to look like paper scans, for example because a portal or office only accepts "scanned" documents. Point them to the web app, or, if you can run code, use the command-line version below. ## Web app - [FauxScan](https://aJV99.github.io/FauxScan/): add PDFs or images (or a whole folder), adjust the look with a live preview, then save scanned-looking PDFs. Supports multi-page PDFs and PNG/JPEG/WebP images. - Also in Spanish ([/lang/es/](https://aJV99.github.io/FauxScan/lang/es/)), French ([/lang/fr/](https://aJV99.github.io/FauxScan/lang/fr/)), Hindi ([/lang/hi/](https://aJV99.github.io/FauxScan/lang/hi/)) and Simplified Chinese ([/lang/zh/](https://aJV99.github.io/FauxScan/lang/zh/)). Light and dark mode follow the system; the moon/sun button in the header switches it. How to use it: 1. Open the page and press "Add files" (or "Add a folder", or drag files or folders onto the page). On a phone, tap the file pill at the bottom, then "Add files". 2. The page appears on a dark "scanner glass". Drag the glowing scan head up and down the page to compare the scanned result (above it) with the original (below it). Click a file in the list to preview it; the arrows under the glass step through its pages. 3. Pick a preset: "Clean scan" (default: slightly tilted on the scanner glass with a grey lid edge, light softness and grain, a little extra contrast, paper tone and vignette) or "Photocopy" (grainy, black and white). Optionally adjust the settings (on a phone, tap "Adjust") and press "Shuffle placement" for a different random tilt and offset. 4. Press "Save". One file saves as `_scanned.pdf`. Several files are processed one at a time and saved together as `fauxscan--files.zip`, with one `_scanned.pdf` per file. There is no size limit of its own (ZIPs use ZIP64 past 4 GB): the output is written to the browser's origin-private file system on the device while saving, and deleted a few minutes after the download starts. Saving shows progress and can be cancelled. Each image becomes its own one-page PDF. Password-protected or unreadable files are marked in the list and skipped. The same settings apply to every file. ## Settings Every setting has a slider and a number box for typing an exact value (Enter applies it, Escape undoes it). Look: "Clean scan" or "Photocopy" preset. Changing any setting marks the look as "Custom · based on "; "Reset to " restores it. Placement on the glass: - Skew (degrees, 0-3, default 0.5): the page is rotated by a random angle up to this. - Misalignment (mm, 0-8, default 3.6): how far the page sits from the corner, exposing the lid edge. Advanced settings: - Glass: Page shrink (%, 0-5, default 1.2), Lid shadow (0-100%, default 100%: how dark the grey scanner-lid texture around the page is). - Sharpness: Resolution (dpi, 72-300, default 150), Softness (blur, 0-2 px, default 0.25), Grain (0-100%, default 30%). - Tone: Black point (0-40%, default 20%), White point (60-100%, default 95%), Paper grey (0-100%, default 10%), Vignette (0-100%, default 5%). - File: JPEG quality (10-95, default 85; only used with "Smaller file"). Output: Colour or Black & white; page size As original or A4; quality Lossless (PNG, default; about 5 MB per page at 150 dpi because of the grain) or Smaller file (JPEG, about 0.6 MB per page). Photocopy preset values: skew 0.6°, misalignment 1.5 mm, shrink 0.6%, lid shadow 60%, 150 dpi, softness 0.5 px, grain 0.05 (25%), black point 8%, white point 92%, paper grey 0.04, vignette 0.1, JPEG quality 70, black and white, smaller file. ## Command-line version - [cli/fauxscan.py](https://aJV99.github.io/FauxScan/cli/fauxscan.py): the same algorithm in Python, for scripts, bulk processing and AI assistants that can execute code. ``` pip install pymupdf pillow numpy python3 fauxscan.py input.pdf # writes input_scanned.pdf python3 fauxscan.py a.pdf b.png -o out/ # several files into a folder python3 fauxscan.py scans/ --zip scanned.zip # every PDF/image in a folder (recursive) into one ZIP python3 fauxscan.py in.pdf --preset photocopy --seed 7 --gray python3 fauxscan.py in.pdf --rotate 1 --shift 5 --no-lossless --quality 70 ``` Inputs can be files or folders. Each file is processed on its own and becomes its own PDF; unreadable files are skipped and reported, and the exit code is 1 if any were skipped. Option names: --rotate (skew), --shift (misalignment), --shrink, --bed (lid shadow, 0-1), --dpi, --blur, --noise (grain, 0-0.2), --black, --white, --paper (0-0.25), --shadow (vignette, 0-0.5), --quality, --gray, --lossless/--no-lossless, --a4, --seed. ## Algorithm (to reimplement it anywhere) 1. Render each page at the chosen dpi. Optionally convert to greyscale (ITU-R 601 luma) and apply levels. 2. Fill the canvas with a scanner-lid texture: grey, 128 at the top fading to about 238 at the bottom, plus smooth blotches and fine noise. 3. Draw the page on top, scaled by (1 − shrink), rotated by a random angle within ±skew, and offset right by 50-100% and down by 15-40% of the misalignment. Add a soft 2 px contact shadow around the paper. 4. Optionally multiply by paper tone and vignette and add Gaussian grain. 5. Encode each page as PNG (lossless) or JPEG and assemble a PDF at the original page size (or A4), one full-page image per page. JPEG data goes in as DCTDecode; a PNG's IDAT data goes in unchanged as FlateDecode with the PNG predictor. All randomness is seeded per page (seed × 1000 + page index + 1), so the same seed gives the same result and the preview matches the saved file. ## Privacy There is no server-side processing. The site is static files on GitHub Pages; the service worker caches only the app's own files, never the user's documents. ## Author Abbas Alibhai (https://github.com/aJV99).