27 lines
1.5 KiB
Markdown
27 lines
1.5 KiB
Markdown
# Architecture
|
||
|
||
The React workbench owns an in-memory ordered list of source `File` objects and
|
||
serializable page settings. No page content enters local storage. Each source is
|
||
decoded with `createImageBitmap`; its dimensions and byte size are checked before
|
||
it joins the workspace.
|
||
|
||
The renderer downscales exceptionally large source rasters to a 24-megapixel
|
||
working ceiling. A projective map sends every destination pixel through the four
|
||
selected source corners and samples it bilinearly. A bounded pixel pass applies
|
||
brightness, contrast, perceptual grayscale and optional Otsu/manual threshold.
|
||
Canvas rotation handles quarter turns and the final ±5 degree deskew. Preview,
|
||
OCR and export call the same renderer with different disclosed pixel budgets, so
|
||
the preview semantics match the downloaded result.
|
||
|
||
Deskew estimation downsamples to at most 420 pixels on the long edge, tests
|
||
half-degree candidates from −5 to +5, and scores the horizontal projection of
|
||
dark pixels. It declines to invent an angle when insufficient foreground exists.
|
||
|
||
PDF export dynamically loads jsPDF, renders pages sequentially, JPEG-encodes
|
||
each bounded page, and fits it into the selected physical page. OCR dynamically
|
||
loads Tesseract.js only after user confirmation. Its worker, three LSTM-only
|
||
runtime variants and English integer trained data are copied from pinned npm
|
||
packages to same-origin release assets. Tesseract's persistent model cache is
|
||
disabled, one in-memory worker is reused and can be terminated, and no fallback
|
||
CDN path is used.
|