Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Release CI Issues Python 3.12 Platforms Made in France License: PolyForm Shield


Aglaïa

Turn a webcam and a stack of pages into clean, deskewed, dewarped, searchable PDFs — locally, on your machine.
Explore the docs »

Website · Download · Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. How It Works
  5. Roadmap
  6. Contributing
  7. License
  8. Contact
  9. Acknowledgments

About The Project

The goal of this project is to provide a simple, comprehensive, extendable, tool for end-to-end book scanning.

Book scanning is usually done using custom rigs — eg Custom rigs on diybookscanner.org

This is a fine way of doing things which has many advantages : you control the perspective, the geometry, the illumination, … BUT it is not portable and requires a quite substancial time and resources investment.

At the other end of the spectrum you have ugly phone pictures, and a myriad of "Free Scanner" aps on the iOS appStore which all repackage the simple homography and detection primitives of the Apple Vision SDK : if you are not scanning flat sheets of paper you are out of luck

Aglaia wants to do the following : Provide a comprehensive solution to book scanning, ie allow to use physical books and the tools you have (a laptop and a phone, maybe a camera) in any situation you could be (at your desk, on bench outside, at the libray…) to produce high-quality digital materials suitable for :

  • archiving, indexing and printing : clean, OCRed PDFs
  • feeding knowledgebases and AI research tools : well structured Markdown files

The slider section on the project website demonstrates this purpose : 3 different scanning situations

Aglaïa's purpose is similar to Scantailor's, but it tries to reduce the friction with better import (images, pdf or capture), exports (pdf with OCR, markdown, ...), built-in OCR, extendability through custom pipelines, exporters and plugins and more modern algorithms.

What the default pipeline will do to a standard book ?

In a few word Aglaïa will produce precisely cut binarized text pages with perspective and page curvature correction. On a modern laptop it can process roughly 1 page / sec.

To achieve it, it relies on :

  • a coarse scan-based deskewing followed by a robust and precise page extraction using lightweight ML text recognition models
  • a finer page based deskewing followed by a robust binarization which can tolerate very unequal illumination and handle border constraints
  • keystone and page curvature correction. This is the most computationally demanding part, handed out to JAX/CUDA or JAX/MLX libraries if available
  • a final replay to intelligently compose the coordinate and morphological transforms to avoid successive interpolation artifacts, especially severe on bilevel images

Operator composition (Smart replay) prevents re-interpolation artifacts

(back to top)

How much does it costs ?

It's free. Donations are appreciated to help cover developpement costs (signing and notarization, AI coding tool)

Built With

  • Python managed with uv
  • PySide6 — cross-platform desktop GUI
  • OpenCV · NumPy · SciPy · Pillow — image processing
  • page-dewarp + JAX / MLX — cubic-sheet page dewarp (MLX on Apple Silicon). The original project has been highly modified and extended
  • doxapy — binarization (Wolf / Sauvola)
  • pikepdf · pypdfium2 — PDF I/O
  • Apple Vision · Apple Document (pyobjc, macOS) — OCR and layout, with EAST/DBnet fallbacks
  • Surya 2 · GLM-OCR · Unlimited-OCR · Mistral Document AI — cross-platform OCR engines (local VLMs via MLX or vLLM; Mistral in the cloud, synchronous or batch)
  • Vosk — offline voice control (cross-platform)
  • SQLite — one .agl file per project: images, every pipeline step, OCR results, per-page corrections

(back to top)

Getting Started

Download

Grab the latest build for your platform — the release CI publishes fixed-name "latest" artifacts, so these links never go stale:

Platform Download Notes
macOS (Apple Silicon) Aglaia-macos-arm64.dmg Signed + notarized. Open and drag to Applications.
Windows (x64) Aglaia-windows-x64-setup.exe Installer; registers the .agl file type. Not code-signed — SmartScreen will warn; click More info → Run anyway. Verify with SHA256SUMS-windows.txt.
Linux (x86_64) Aglaia-x86_64.AppImage CPU dewarp. chmod +x, then run. Needs FUSE (fuse2).

Install from the command line

CLI-only or scripted setups (any platform) install via uv or pip:

# from PyPI — installs the `aglaia` command
pip install aglaia                  # lean base: headless pipeline, no Qt
pip install "aglaia[gui]"           # Windows / Linux GUI (Qt)
pip install "aglaia[gui,macos]"     # macOS GUI: Vision, Speech, MLX dewarp
pip install "aglaia[server]"        # HTTP job server (FastAPI + uvicorn)
# or build from source with the extras you want
git clone https://github.com/yb85/aglaia.git && cd aglaia
uv sync --extra gui --extra macos   # macOS GUI
uv sync --extra gui                 # Windows / Linux GUI
uv sync                             # headless: CLI pipeline, no Qt

Optional extras: --extra macos (Apple Silicon: MLX-served local VLM OCR — GLM-OCR / Unlimited-OCR / Surya), --extra cuda (NVIDIA: vLLM-served local VLM OCR), --extra voice (Vosk), --extra server (FastAPI + uvicorn HTTP job server).

Local VLM OCR (--ocr glm / --ocr unlimited / --ocr surya) serves through a bundled-by-platform backend: --extra macos ships the MLX backend (Apple Silicon), --extra cuda ships vLLM (Linux, GPU or CPU). So on a Mac the GUI install (--extra gui --extra macos) already includes local VLM OCR; on a Linux GPU box use --extra cuda. Surya 2 goes through that same backend — there is no surya extra any more.

First run (CLI-only installs): run the one-time setup to pick and download the offline models, seed the default pipelines, and bootstrap the config:

aglaia setup        # interactive: choose models (DBnet, EAST, Surya…), download, configure

This is the terminal equivalent of the GUI's first-run wizard. A headless batch run refuses to start until the install is configured (aglaia setup or the GUI). The GUI installs run the wizard automatically on first launch.

[!WARNING] Build with the right options The --extra options are mandatory to interface models and backends with python. If you download the models or install cuda drivers on your computer but forget to include teh relevant extra options, they won't be used

(back to top)

Usage

Aglaïa is a subcommand CLI — aglaia <command> [options]. gui is the default command, so a bare invocation (or one with a project path) opens the capture GUI. From source, prefix with uv run.

# Capture GUI (webcam + processing chain + voice control) — `gui` is the default
uv run aglaia                        # or just `aglaia` once installed
uv run aglaia ~/scans/my-book        # open/create a project in the GUI
uv run aglaia gui --camera-id 1      # explicit form

# Headless batch — same chain, no Qt
uv run aglaia run ~/scans/*.jpg --ocr auto --export pdf:g4+md
uv run aglaia run ~/scans/my-book.agl -p book_curved_x2 --ocr surya:lang=fr-FR

# OCR a clean PDF/scan with NO processing (no dewarp/binarize)
uv run aglaia ocr ~/scans/clean.pdf --export pdf:g4+md

Commands:

Command What it does
gui [PROJECT] Capture GUI (default). --camera-id N, --diagnose-memory.
run PATHS… Headless batch over images, PDFs, or one .agl. --ocr ENGINE[:opt…] (now needs a value — use --ocr auto), --ocr-lang, --export (pdf, md, textpack), --md-refine, --send-to SLUG[+SLUG…], --project-name, --parent-dir, --input-dpi [force:]N, --check-ocr.
ocr PATHS… OCR PDFs/images (or re-OCR a .agl) with no processing chain — for already-clean docs. Same OCR/export options as run, minus --pipeline/--workers/--force-proc. Engine defaults to auto.
setup Interactive first-run setup (choose/download models, seed config).
list pipelines|ocr|exports|destinations Introspect available pipelines, OCR engines, export formats, installed destinations.
plugins … The plugin store from the terminal: list, search, install, update, toggle, remove, config.
server HTTP job server (see below).
version Print the version (--version also works).
skill Print the agent skill file that documents this CLI.

Shared options (on gui and run): -p/--pipeline NAME|PATH (book_curved_x2 resolves to the bundled pipeline, or pass a .yaml), --workers N (0 = auto), --force-proc.

The import panel / run accept multiple images and PDFs (per-page extract or render). Page detection defaults to DBnet (auto resolves DBnet → Apple Vision on macOS → EAST); aglaia setup and the in-app downloader fetch the models, or drop them into ./model/ / ./models/.

Migrating from the flat CLI: the old flags are gone (clean break, pre-1.0). --headless → run, --setup → setup, --pipeline-list/--ocr-list/--export-list → list …, and a bare --ocr now needs a value (--ocr auto).

Server

aglaia server (needs the server extra) runs a long-running HTTP job API on port 4674. Submit a captured bundle (from the aglaia-bridge iOS app) or a PDF and get back a searchable PDF — plus Markdown when OCR is on; the transient .agl is never kept.

uv run aglaia server --host 0.0.0.0 --port 4674 --public-url https://scan.example.com

Endpoints include POST /run (API key; upload + email_notif, ocr, dpi), GET /list, GET /check/{id}, GET /get/{id}, GET /download/{id}/{pdf|md} (capability URL — the unguessable job_id is the secret, so email links need no key), POST /delete/{id}, an admin console (GET /admin + POST /admin/keys / …/revoke, keys tied to emails), and GET /health. Mistral OCR runs as a batch with exponential-backoff polling; a completion email (when requested) carries the download links.

Receive from phone

The iOS companion app aglaia-bridge (separate repo) captures book pages on your phone and pushes them to the desktop over the LAN — QR-bootstrapped, TLS-pinned. Use the Import tab's Receive from phone button to pair.

For the full guide, see the documentation.

(back to top)

How It Works

capture → DPI fix → deskew → layout detect → keystone → dewarp → binarize → OCR → export

Every step is a pluggable processor defined in a YAML pipeline. Add your own by dropping aglaia/processors/<NewProc>.py (the registry auto-discovers it) — or, at runtime, drop a .py into <APP_DATA>/plugins/ and approve it in the trust prompt. See Architecture and Processors.

(back to top)

Contributing

Work is tracked via GitHub issues + milestones — one issue per discrete unit of work. Before non-trivial work, open an issue. Branch names reference it (feat/123-slug); PRs close via Closes #N.

  1. Fork the project
  2. Create your branch (git checkout -b feat/123-amazing-feature)
  3. Make changes; keep ruff, mypy --strict, and pytest green
  4. Commit (git commit -m 'feat: add amazing feature')
  5. Push and open a Pull Request

(back to top)

License

Source-available under the PolyForm Shield License 1.0.0 — see LICENSE.

[!WARNING] This is not strictly-speaking "open-source" !

the reason is not to make it one day a commercial product, but to avoid trivial SaaS repackaging which hurts the developpment of free Apps.

You may use, modify, and redistribute the software for any purpose except building a product that competes with it. Otherwise free.

Repackaging it and removing the donation link is direct competition.

(back to top)

Contact

aglaia@bibli.cc

Project: github.com/yb85/aglaia · Website: aglaia.bibli.cc

(back to top)

Acknowledgments

See ABOUT page.

(back to top)

Metadata

Release files for aglaia 0.1.0rc8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aglaia 0.1.0rc8
File Size Uploaded
aglaia-0.1.0rc8.tar.gz 15.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for aglaia 0.1.0rc8
File Interpreter ABI Platform
aglaia-0.1.0rc8-py3-none-any.whl Python 3 none any Details

Total release size: 31.7 MB

Release files / aglaia-0.1.0rc8.tar.gz

Download URL aglaia-0.1.0rc8.tar.gz
Size 15.8 MB
Tags Source
SHA-256 checksum
How to use checksums
4ea249acaf581c9c5941e7acbbb34141703db33e914791ea426220fb9005358c
BLAKE2b-256 checksum
How to use checksums
23cb4a72af407c5d45cd17104ea906bca6732fee9914e977db41693e3b9b4fe7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / aglaia-0.1.0rc8-py3-none-any.whl

Download URL aglaia-0.1.0rc8-py3-none-any.whl
Size 15.9 MB
Tags Python 3
SHA-256 checksum
How to use checksums
b192ae9f6a5dc442191eab8ced6fbcac851b458f395fe75262c4f893fa085889
BLAKE2b-256 checksum
How to use checksums
1d19432bc62fb57c63f7640723c64dbf3e51598442c519bd4e8a7f41f66c27be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page