scanlayer
Docs / Reference

Configuration

Most tunables live in config.py, grouped by pipeline stage. Editing that file directly only works from a source checkout; once installed via pip, it lives in site-packages and is not meant to be touched. Use configure() or a config file instead.

scanlayer.configure(**overrides)

python
import scanlayer
scanlayer.configure(lang="eng", min_word_confidence=40)

Raises ValueError on an unknown key, so a typo fails loudly instead of silently doing nothing.

Accepted keys tesseract_cmd, tessdata_dir, lang, default_dpi, min_word_confidence, psm_candidates, psm_early_exit_confidence, psm_parallel, psm_max_workers, ocr_timeout_seconds, char_whitelist, char_blacklist, jpeg_quality, font_path, log_level, log_timing, multi_column_detection, column_min_gutter_fraction, column_gutter_vote_fraction, column_full_width_line_fraction, column_min_lines_for_detection

Config files

bash
scanlayer invoice.jpg -o invoice.pdf --config settings.json
pythonapply_config.py
scanlayer.configure_from_file("profile.yaml")
scanlayer.configure(lang="eng")  # override specific keys afterward
jsonsettings.json
{
  "tesseract_cmd": "/usr/bin/tesseract",
  "lang": "fra+eng",
  "default_dpi": 300,
  "min_word_confidence": 40,
  "psm_candidates": [3, 4, 6, 11],
  "multi_column_detection": true,
  "jpeg_quality": 82,
  "log_level": "INFO"
}

The same profile as YAML, if you've installed the yaml extra:

yamlprofile.yaml
tesseract_cmd: /usr/bin/tesseract
lang: fra+eng
default_dpi: 300
min_word_confidence: 40
psm_candidates: [3, 4, 6, 11]
multi_column_detection: true
jpeg_quality: 82
log_level: INFO

Every key here matches a configure() keyword argument one-for-one; see Key tunables by stage below for the full list and what each one does.

YAML needs an extra dependency A .yaml/.yml config file requires PyYAML, which scanlayer does not install by default. Install it with pip install scanlayer[yaml], or with plain pip install pyyaml from a checkout. Use a .json config file instead if you would rather not add the dependency; the two formats are otherwise interchangeable.

Precedence (highest to lowest)

  1. Arguments passed directly to convert() (lang=, dpi=, …), or the equivalent CLI flags
  2. scanlayer.configure(...) calls made at runtime, or a --config file (a CLI-supplied config file is applied before other CLI flags, so a flag still overrides it)
  3. Environment variables (TESSERACT_CMD, SCANLAYER_LOG_LEVEL, …), read once at import time
  4. Hardcoded defaults in config.py

Key tunables by stage

OCR

SettingDefault
DEFAULT_OCR_LANG"fra+eng"
MIN_WORD_CONFIDENCE35
TESSERACT_PSM_CANDIDATES[3, 4, 6, 11], see CLI Reference
PSM_EARLY_EXIT_CONFIDENCE80.0
PSM_PARALLELTrue
PSM_MAX_WORKERSunset (thread-pool default)
OCR_TIMEOUT_SECONDS45
TESSERACT_OEM1 (LSTM only)
TESSERACT_CHAR_WHITELIST / _BLACKLISTNone
DROP_NON_PRINTABLE_WORDSTrue, drops words containing non-printable/control characters

Image preprocessing

SettingDefault
OCR_UPSCALE_MIN_WIDTH2500
OCR_DOWNSCALE_MAX_WIDTH3500
APPLY_EXIF_ORIENTATIONTrue
UNSHARP_AMOUNT / UNSHARP_SIGMA0.5 / 1.2
DENOISING_H10
CLAHE_CLIP_LIMIT / CLAHE_TILE_GRID2.0 / (8, 8)
DESKEW_MIN_PIXELS100
DESKEW_MIN_STD5.0, the blank-page threshold
DESKEW_MIN_ANGLE0.3°
DESKEW_MAX_ANGLE30.0°
PREPROCESS_TRY_ADAPTIVE_THRESHOLDFalse, experimental adaptive-thresholding pass (currently unused in the default pipeline)

Multi-column reading order

SettingDefault
MULTI_COLUMN_DETECTIONTrue, master switch
COLUMN_MIN_GUTTER_FRACTION0.03
COLUMN_FULL_WIDTH_LINE_FRACTION0.62
COLUMN_MIN_LINES_FOR_DETECTION6
COLUMN_GUTTER_VOTE_FRACTION0.6
Tuned for prose, not tables A table's narrow per-row gutters will not trigger multi-column detection, see Roadmap & Limitations.

PDF output

SettingDefault
PDF_JPEG_QUALITY82
PDF_ADAPTIVE_COMPRESSIONTrue
PDF_GRAYSCALE_THRESHOLD0.02
FONT_PATHNone, auto-selects a CJK CID font, bundled DejaVu Sans, or Helvetica, based on lang
PDF_METADATAtitle/author/subject/creator defaults

Logging

SettingDefault
LOG_LEVELenv SCANLAYER_LOG_LEVEL, default "INFO"
LOG_TIMINGTrue
Read the comments in config.py before changing defaults Several values, deskew and blank-page thresholds especially, were tuned against real scanned and photographed pages, not chosen arbitrarily.

get_settings()

python
scanlayer.get_settings()  # -> dict of every configure()-able key, current value