Skip to main content
scanlayer

scanlayer

Turn scanned image or photographed document into searchable PDF, or raw OCR text/JSON/TSV/hOCR.

Turn a scanned image or photographed document into a searchable PDF, or export the raw OCR result as plain text, JSON, TSV, or hOCR. Use it as a command-line tool or as a Python library; both are the same engine underneath.

PyPI version codecov Python Platforms GitHub last commit License: MIT


Documentation

Full documentation – installation, CLI & API reference, configuration, output formats, examples, and troubleshooting.

What it does

A scanned invoice, a phone photo of a letter, a stack of photographed pages: scanlayer runs it through Tesseract OCR and gives you back either:

  • a searchable PDF: the original page image, with an invisible, precisely positioned text layer over it, so you can select and search text exactly where it visually appears, or
  • the raw OCR result as txt, json, tsv, or hocr: text, per-word confidence, and bounding boxes, no PDF built at all.

Along the way it automatically straightens rotated/skewed pages, corrects uneven lighting, denoises and sharpens for OCR accuracy without touching what you actually see in the output, reconstructs correct reading order on genuine multi-column pages, and races several OCR configurations against each other to pick the most confident result.

Two interfaces, one engine scanlayer CLI and import scanlayer call the exact same pipeline
Five output formats Searchable pdf, or raw txt / json / tsv / hocr
Real column detection Two-column articles/letters read in correct order, not interleaved
Batch, merge, native PDF input Convert a folder in one call, merge pages into one PDF, or --dry-run a batch before spending time on OCR
One configuration surface configure(), a JSON/YAML profile, or CLI flags, documented precedence
Debug overlay --debug-image draws every word, color-coded by confidence

See the feature catalog for the complete list, and Roadmap & Limitations for what's deliberately out of scope or not built yet.

Requirements

  • Python 3.9+
  • Tesseract OCR (a separate, system-level install, see below)
  • poppler only if you feed scanlayer a native .pdf file directly
# Debian / Ubuntu
sudo apt install tesseract-ocr poppler-utils

# macOS (Homebrew)
brew install tesseract poppler

# Windows: Tesseract -> https://github.com/tesseract-ocr/tesseract/wiki
#          poppler    -> download a release, add its bin/ to PATH

Full detail, including how scanlayer locates the Tesseract binary automatically and how to bundle your own, is in Installation and Bundling Tesseract.

Install

pip install scanlayer

This installs the scanlayer console command and makes import scanlayer available anywhere on the machine.

Working on scanlayer itself, or want to run it straight from a checkout with no install at all?

git clone https://github.com/Hyacinthe-primus/scanlayer.git
cd scanlayer                        # the repo root, which contains requirements.txt
pip install -r requirements.txt
python -m scanlayer invoice.jpg -o invoice.pdf   # works with no install at all

See CONTRIBUTING.md for the full contributor setup (editable install and running the test suite).

Quick start

As a CLI:

scanlayer invoice.jpg -o invoice.pdf --lang fra+eng --dpi 300

As a library:

import scanlayer

result = scanlayer.convert("invoice.jpg", "invoice.pdf", lang="fra+eng", dpi=300)
print(f"{result.words_count} words, {result.mean_confidence:.1f}% confidence")

Every CLI flag and library keyword argument in this project are named to match each other (--lang ↔ lang=, --dpi ↔ dpi=, and so on), see Examples for every feature shown both ways, side by side, and CLI Reference / Library API for the complete details of each.

A few more common cases:

# Batch-convert a folder
scanlayer *.jpg -o ./converted/

# Merge several photographed pages into one searchable PDF
scanlayer page1.jpg page2.jpg page3.jpg -o report.pdf --merge

# Export raw OCR text/JSON instead of a PDF
scanlayer invoice.jpg -o invoice.json --format json

# See what OCR actually detected, color-coded by confidence
scanlayer invoice.jpg --debug-image

# Validate a batch before spending time on OCR: files exist,
# Tesseract reachable, output paths writable
scanlayer *.jpg -o ./converted/ --dry-run
import scanlayer

# Batch
result = scanlayer.convert_batch(["*.jpg"], "./converted/")

# Merge
scanlayer.convert_merge(["page1.jpg", "page2.jpg", "page3.jpg"], "report.pdf")

# Raw export
scanlayer.convert("invoice.jpg", "invoice.json", output_format="json")

Repository layout

.
├── .github/           # FUNDING.yml
├── scanlayer/         # library source
│   ├── __init__.py
│   ├── __main__.py    # enables `python -m scanlayer`
│   ├── main.py        # public API: convert()/convert_batch()/convert_merge()
│   ├── config.py
│   ├── cli/           # argparse CLI: parser.py, run.py, dry_run.py
│   ├── fonts/         # bundled DejaVu Sans for the PDF text layer
│   ├── preprocessing/
│   ├── ocr/
│   ├── layout/
│   ├── pdf/
│   └── utils/
├── tests/             # pytest suite
├── pyproject.toml
├── requirements.txt
├── README.md
├── CONTRIBUTING.md
├── SECURITY.md
└── LICENSE.md

Contributing

Bug reports, fixes, and feature discussions are welcome: see CONTRIBUTING.md for how to set up a development environment and what to include in a pull request. There is a tests/ directory (now including utils/validators.py and the --dry-run flag, with cross-platform coverage for Tesseract discovery on Windows/macOS/Linux) and it runs with pytest automatically in CI on every push and pull request; see Roadmap & Limitations and the Adding tests section of the contributing guide for where coverage is thinnest.

Support the project

scanlayer is free and MIT-licensed, maintained in spare time. If it saves you time, there is no fee – but a little support goes a long way:

  • Star the repository – the simplest signal that the project is worth maintaining.
  • Report bugs or request features by opening a GitHub Issue.
  • Contribute a fix, test, or example – see CONTRIBUTING.md.

License

This project is licensed under the MIT License.

Metadata

Release files for scanlayer 1.0.3

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

Source distribution (sdist)

Source distribution for scanlayer 1.0.3
File Size Uploaded
scanlayer-1.0.3.tar.gz 438.5 kB Details

Built distribution (wheel)

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

Total release size: 871.0 kB

Release files / scanlayer-1.0.3.tar.gz

Download URL scanlayer-1.0.3.tar.gz
Size 438.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c5defb2d28b1efe643d12ebb1a443c24e503e67fc2a1b54914fc88210a390cd6
BLAKE2b-256 checksum
How to use checksums
3b06f1775c617a88e3da1a069194f11ea48873c750d2d1e3bbeae13d765b954e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / scanlayer-1.0.3-py3-none-any.whl

Download URL scanlayer-1.0.3-py3-none-any.whl
Size 432.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b28c34458fa20ce464be4576d7443e75340f9ea5911f02dc22724dc051ff501e
BLAKE2b-256 checksum
How to use checksums
33e59e165b2610859ac73b9e709dcce151b9d234d773ddf6f396a5c51f21d8c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

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