A privacy-focused, smartphone-first document scanner that turns paper into a submission-ready PDF entirely in the browser.
Capture a document, correct perspective, organize multiple pages, apply A4 / B&W / file-size requirements, and save or share the final PDF without uploading the document to a server.
GitHub Pages delivers the initial HTML. After it loads, camera capture, image import, corner detection, perspective correction, filtering, page organization, PDF generation, and file-size adjustment are processed locally on your device.
The photos and documents you select are not uploaded by the app.
Japanese UI: screenshot.png
- Camera-first document capture with a native-app-style UI on smartphones
- Explicit camera ON / OFF control that releases the active
MediaStreamwhen disabled - Rear-camera preference, camera switching, and torch control when supported by the device
- Native camera zoom when available, with centered digital zoom up to 4× as a fallback
- Pinch / swipe / slider zoom controls on smartphones
- Optional automatic capture when the document becomes stable
- Local four-corner document detection using edge strength, paper/background contrast, robust line consistency, and quadrilateral geometry, with manual corner adjustment, 1–4× zoom, wheel/pinch zoom, and panning for precise placement
- Perspective correction for skewed photos
- Multi-page scanning workflow
- Drag-and-drop page reordering (with a dedicated touch grip for reliable cross-row moves)
- Three-column page grid on smartphones
- Actual corrected-result preview with No enhancement / Auto / Color / Grayscale / B&W readability modes; Auto uses conservative, smoothly interpolated illumination correction to avoid tiled artifacts and excessive whitening
- Reopen any saved page from its Preview action to change readability or corners
- Smartphone Scan / Pages / PDF bottom navigation switches page-like views instead of scrolling between sections
- Editable output filename with automatic
.pdfextension - Submission presets for 1 MB, 2 MB, A4, and B&W
- Adaptive JPEG quality and resolution reduction for file-size limits
- Portrait and landscape A4 output
- Pre-submit checks showing the final PDF size and selected conditions
- Download and Web Share API support
- Japanese and English UI in the same HTML
- Responsive desktop and smartphone layouts
- No runtime CDN, external font, analytics, telemetry, or server-side processing
The app is designed for the awkward last step of online paperwork.
Typical problems include:
- The photo is skewed or shot at an angle.
- Three pages need to become one PDF.
- The destination requires A4 pages.
- The portal accepts only files under 1 MB or 2 MB.
- The document must be B&W.
- The final file needs to be shared immediately from a phone.
Submission PDF Scanner treats those requirements as part of the scan workflow instead of making the user fix them afterward in another app.
Just open the demo. No installation or account is required.
The app opens with the camera off. Choose Start camera or a camera power control when needed; Add images works without camera access. You can turn the camera off at any time from the camera UI.
- Download
dist/index.htmlfrom this repository. - Open it in a current Chromium-based browser, Firefox, or Safari.
- Choose Start camera and allow access when prompted, or use Add images without starting the camera.
Desktop Chrome is also an explicit file:// target. The app does not block camera startup simply because the HTML was opened directly from disk.
Browser camera permission behavior can still vary by browser and operating system.
- Download or clone this repository.
- Double-click
build-standalone.baton Windows, or run the PowerShell builder. - Copy the generated
dist/index.htmlwherever you need it. - Open that single file later without an internet connection.
No Python, Node.js, or local web server is required for normal use of the generated HTML.
- Open the app and turn the camera on when needed, or import one or more existing images.
- Adjust zoom so the whole document is visible.
- Capture the page.
- Check the actual corrected result, switch to Adjust corners when needed, zoom in if useful, and drag the handles to refine the document boundary.
- Choose No enhancement, Auto, Color, Grayscale, or B&W and add the page.
- Repeat for additional pages.
- Drag page cards to reorder them. On touch screens, use the grip at the top right for reliable vertical or cross-row moves.
- Enter the output filename.
- Choose a submission preset such as 1 MB, 2 MB, A4, or B&W, or use custom settings.
- Generate the PDF, review the final size and pre-submit checks, then save or share it.
- Power — starts or completely stops the camera stream.
- Torch — available only when the active camera and browser expose torch control.
- Camera switch — switches between available video-input devices.
- Zoom — uses native track zoom when available; otherwise the app uses centered digital cropping.
- Auto capture — optionally captures when the document remains stable.
- Add images — imports photos or scans already stored on the device.
When the camera is turned off, the active video tracks are stopped instead of leaving the camera running in the background.
| Preset | Behavior |
|---|---|
| Standard | Keeps normal output settings without a strict size limit |
| 1 MB | Reduces JPEG quality and resolution as needed to target 1 MB or less |
| 2 MB | Reduces JPEG quality and resolution as needed to target 2 MB or less |
| A4 | Places pages on portrait or landscape A4 sheets |
| B&W | Generates monochrome document pages |
File-size presets are best-effort. Extremely image-heavy documents may require stronger quality reduction, so always verify small text in the generated PDF before submitting it.
The repository includes a workflow that builds the standalone HTML and deploys it to GitHub Pages.
- Push the repository to GitHub as
htmlapps-document-scanner. - Open Settings → Pages → Build and deployment → Source and select GitHub Actions.
- Push to
main, or manually run the Pages deployment workflow from the Actions tab. - After a successful deployment, the demo is available at
https://ttomohisa.github.io/htmlapps-document-scanner/.
Each push to main rebuilds and verifies the standalone files before deployment.
.
├─ src/index.template.html # Application source
├─ app.config.json # Product metadata
├─ dependencies.json # Embedded dependency definitions
├─ build-standalone.bat # Windows build entry point
├─ build-standalone.ps1 # Standalone HTML builder
├─ scripts/
│ └─ check-repository.ps1 # Repository / standalone verification
├─ dist/
│ ├─ index.html # Readable standalone release
│ └─ index.self-extract.html # Gzip self-extracting standalone release
└─ .github/workflows/
├─ build-standalone.yml # Pull request build validation
└─ deploy-pages.yml # Automatic GitHub Pages deployment
Edit src/index.template.html, not the generated files under dist/.
powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\build-standalone.ps1
powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\scripts\check-repository.ps1The build produces:
dist/index.htmldist/index.self-extract.html- build and dependency manifests
dist/.nojekyll
The verifier checks the generated standalone files for unresolved placeholders and unintended external runtime dependencies.
The application is intentionally local-first.
- Camera frames and imported images stay in browser memory.
- Perspective correction and image filtering run locally.
- PDF generation runs locally.
- The generated PDF is exported only after a user action.
- The runtime Content Security Policy includes
connect-src 'none'. - The app has no analytics, telemetry, account system, cloud storage, or document upload API.
The GitHub Pages version naturally requires an initial request to load the HTML. After that, the document-processing workflow does not upload the scanned content to the app's server.
For a completely disconnected workflow, open the generated dist/index.html directly from disk.
- Camera access depends on browser and OS permission settings.
- Desktop Chrome can attempt camera access when the generated HTML is opened directly with
file://. - Other browsers may apply different local-file camera policies.
- Torch, native zoom, and camera switching are capability-detected and may not be available on every device.
- Digital zoom remains available when native camera zoom is not exposed.
- Web Share is available only when supported by the browser and operating system.
If camera access is unavailable, the app can still create PDFs from imported images.
- Automatic corner detection can be inaccurate on low-contrast surfaces, white desks, reflections, deep shadows, or documents whose edges are outside the frame.
- Manual four-corner adjustment is provided for recovery.
- OCR and searchable-text PDF generation are not included.
- File-size targets are best-effort rather than byte-perfect guarantees.
- Very high-resolution photos or large page counts can consume substantial device memory.
- Reloading or closing the tab clears the current scan session because page images are intentionally not persisted.
- Camera capability varies significantly between browsers, webcams, and smartphone camera implementations.
The current v1.0.2 runtime does not require a third-party library for the main scanning and PDF-generation flow.
Perspective correction, image processing, page management, camera handling, and PDF creation are implemented with browser APIs and application code. See THIRD_PARTY_NOTICES.md for the current dependency record.
See SECURITY.md for the trust boundary and file-handling model.
Copyright © 2026 ttomohisa
Licensed under the MIT License.
When importing multiple images (up to 30 per selection), the editor shows the current filename and position. Skip image moves to the next image; Stop import, Close, or Escape stops the remaining queue and keeps pages already added. Full image includes the complete image boundary, within the existing resolution cap.
A completed PDF remains ready when its filename changes. Save and Share use the normalized current filename without rebuilding its contents. Changing pages or PDF settings still requires generating the PDF again. Delete all asks for confirmation and offers the same five-second Undo as deleting a single page. Undo restores the original editable pages before any newly added pages.
Open a saved page with Preview, adjust its crop or readability, then choose Save as new page to keep the original and insert a separate editable version immediately after it. Save changes still updates that page. Close or Escape discards the draft. The original and copy can be edited, rotated, deleted and restored independently. Canceling a drag or returning it to its starting position keeps the finished PDF ready; a real reorder requires regenerating it.
Development checks require PowerShell and Node.js (no npm dependencies): run ./scripts/check-repository.ps1. Workflow tests run against the source, readable release, decoded self-extract release and root document-scanner.html. The default builder refreshes that root catalog release. ./build-standalone.ps1 -OutputDirectory <path> generates an isolated copy without changing the root/default output; ./scripts/verify-standalone.ps1 -OutputDirectory <path> checks it. Verification checks decoded payload parity and manifest hashes, and an isolated regression detects root-release drift and custom-output mutation.
