A webcam-based book inventory scanner. Point your camera at a barcode, and it automatically looks up the book on Google Books and saves it to your local library — organised by physical bookshelf and shelf row.
Built with OpenCV, zxing-cpp, and SQLAlchemy (SQLite by default, PostgreSQL supported).
- Live barcode scanning — continuous EAN-13/EAN-8 detection via webcam
- Named bookshelves — model your actual bookcases; switch between them with
[/]or the on-screen nav bar - Google Books metadata — title, authors, publisher, cover, page count fetched automatically
- SQLAlchemy backend — SQLite out of the box; switch to PostgreSQL (or any other supported DB) via
DATABASE_URL - Snapshot recovery — press
Sto save a tricky barcode image;book-scanner-cleanretries it later with enhanced processing - Audio feedback — sound cues on save (macOS, Windows, and Linux)
- Python 3.11+
- A webcam
- A Google Books API key (optional, but recommended for metadata)
uv tool install git+https://github.com/Zartei/book-scanner
book-scannerThis puts book-scanner and book-scanner-clean on your PATH.
uv add git+https://github.com/Zartei/book-scannerThen either use uv run to launch within the venv:
uv run book-scannerOr activate the venv first:
source .venv/bin/activate # macOS / Linux
.venv\Scripts\activate # Windows
book-scannerNote: the first launch takes a few seconds to load — you'll see
Starting book-scanner…while dependencies initialise.
git clone https://github.com/Zartei/book-scanner
cd book-scanner
uv sync --extra devuv sync --extra postgresCreate a .env file in your working directory:
GOOGLE_BOOKS_API_KEY=your_key_here
# Optional: use PostgreSQL instead of SQLite
# DATABASE_URL=postgresql://user:pass@localhost/bookscanner
# Optional: override where data is stored (default: ~/Library/Application Support/book-scanner)
# BOOK_SCANNER_DATA_DIR=/path/to/your/databook-scannerOn first run you will be prompted to configure your bookshelves — give each physical bookcase a name and tell it how many shelf rows it has. This is saved to bookshelves.json in your data directory and only needs to be done once.
book-scannerPoint the barcode at the camera. Once locked, the book is saved automatically after the snap delay.
Controls:
| Key / Action | Effect |
|---|---|
[ / ] |
Previous / next bookshelf |
1–9 |
Set shelf row within current bookshelf |
i / o |
Decrease / increase auto-snap delay |
S |
Manual snapshot → saved to unread/ for later |
Q |
Quit |
| Left-click | Focus scan on a region of the frame |
The nav bar at the top of the window shows all bookshelves as clickable tabs, with < sh / sh > buttons to step through shelf rows by mouse.
If a barcode wouldn't scan live, press S to save a snapshot. Later, run:
book-scanner-clean --bookshelf living_room --shelf 2This applies CLAHE, sharpening, rotation, and multi-scale retries to decode the image and file the book.
By default data is stored in:
| Platform | Path |
|---|---|
| macOS | ~/Library/Application Support/book-scanner/ |
| Linux / Windows | ~/.book-scanner/ |
Override with BOOK_SCANNER_DATA_DIR.
Structure:
book-scanner/
├── bookshelves.json # your bookshelf config
├── library.db # SQLite database (or unused if DATABASE_URL is set)
├── unread/ # snapshots awaiting processing
├── living_room/
│ ├── shelf_1/
│ │ ├── 9780131103627.jpg
│ │ └── 9780131103627.json
│ └── shelf_2/
└── office/
└── shelf_1/
MIT
Built by Zartei