Split a scanned sheet into individual, deskewed photos — in your browser.
SplitSnap takes a flatbed scan that contains several photos (or cards, receipts, etc.) laid out on a white background, automatically detects each one, straightens any that were scanned at an angle, crops them out, and gives you a review-and-approve workflow before anything is saved.
No more guessing how many photos are on each sheet: SplitSnap detects the count automatically, and lets you override it per scan when you want to.
- Auto-detect how many photos are on each scan — no "photos per scan" to set.
- Grouped review — each scan appears as a row: the original on the left with its cropped photos inline. Approve or reject a whole scan, or Approve All / Reject All.
- Per-scan count override + Retry — bump a scan's count up/down (or leave it on Auto) and re-crop just that scan when detection misses.
- Automatic deskew — straightens each detected photo before cropping.
- Rotate any crop; rotate/flip in the enlarged view.
- Hot-watch — monitor the input folder and pull in new scans automatically (newest on top). Combine with Auto-approve for a fully hands-off pipeline.
- Originals filed away — once all of a scan's crops are approved, the original moves to
processed/(optional). - Quality preserved — crops keep the scan's resolution (DPI) and are saved at maximum quality. Output format is selectable (JPG/PNG/WEBP/TIFF/BMP, + optional filename prefix); PNG and TIFF are lossless.
- Inputs: JPG, PNG, BMP, TIFF, WEBP.
# 1. Install dependencies
pip install -r requirements.txt
# 2. Put your scan images in ./input/
# 3. Start the server
python main.pyThen open http://localhost:8000 and:
- Analyze Input — SplitSnap detects and crops every scan, showing one row per scan (the original plus its cropped photos).
- Fix anything if needed: rotate a crop, or adjust a scan's count and hit Retry to re-crop just that scan.
- Approve a scan (or Approve All) — approved photos go to
./output/and the original is filed to./processed/. Reject to discard. - Or enable Auto-approve (and Hot-watch) to run hands-free.
SplitSnap binarizes each scan (threshold or Otsu), finds external contours, fits a rotated rectangle to each, and keeps the regions that look like photos using absolute filters — area as a fraction of the sheet, aspect ratio, and solidity — followed by non-maximum suppression to drop duplicates. Each kept region is deskewed with an affine rotation and cropped to its bounding box. A "fixed count" mode (take the N largest regions) is available as a manual override.
SplitSnap/
├── core/
│ ├── scanner.py # detection engine: detect → deskew → crop
│ └── processor.py # config + batch orchestration
├── server/
│ ├── app.py # FastAPI app
│ └── routes.py # REST API
├── web/ # browser UI (HTML/CSS/JS)
├── input/ # put your scans here
├── main.py # entry point
└── requirements.txt
SplitSnap is a Python web app — a FastAPI backend with a vanilla HTML/CSS/JS frontend (no third-party JavaScript). It builds on these open-source projects:
| Component | Role | License |
|---|---|---|
| Python | language & runtime | PSF |
| FastAPI | web framework | MIT |
| Starlette | ASGI toolkit (via FastAPI) | BSD-3-Clause |
| Pydantic | request/response models | MIT |
| Uvicorn | ASGI server | BSD-3-Clause |
| Pillow | image I/O, DPI, previews | MIT-CMU (HPND) |
| NumPy | array math | BSD-3-Clause |
OpenCV (opencv-python-headless) |
image processing & detection | Apache-2.0 |
uvicorn[standard] additionally pulls in httptools, websockets, watchfiles, python-dotenv,
and PyYAML (MIT / BSD-3-Clause). Exact pinned versions are in
requirements.txt.
SplitSnap is licensed under the GNU Affero General Public License v3.0 — see LICENSE.
Copyright (C) 2026 TechLuddite
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for details.
Commercial licensing: AGPL-3.0 requires anyone who runs a modified version — including over a network (SaaS) — to make the corresponding source available under the same license. As the sole copyright holder, TechLuddite may also offer SplitSnap under a separate commercial license for users who do not wish to comply with the AGPL. Contact the author for commercial terms.