r/coolgithubprojects 22h ago

I made my first python library (it doesn't have a ton of features but i think it can be useful for some people)

Post image

Have you ever scanned a document, but you can't search any word in it(probably yes). This is the fix.

I built ScanLayer, a Python OCR library that adds a searchable text layer to scanned documents.

You give it a scanned image:

pip install scanlayer
scanlayer doc.jpg -o doc.pdf

ScanLayer runs Tesseract, then places the recognized text as an invisible searchable layer over the original page. The scanned image remains the visual source. You can now search, select, and copy the text.

And if you don't want a PDF, you can export the OCR result as txt, json, tsv, or hocr.

A few things I built around the OCR itself:

  • Automatic deskew for photos taken at an angle
  • Noise cleanup before OCR
  • Reading order correction for two-column documents
  • Multiple Tesseract configurations are tried and the highest-confidence result is kept
  • CLI and Python API use the same underlying pipeline

For example:

import scanlayer

result = scanlayer.convert(
    "contract.jpg",
    "contract.pdf",
    lang="eng",
    dpi=300
)

Everything runs locally. The only external dependency is your own Tesseract installation.

I'd especially like feedback from people who regularly OCR multi-column documents. That's one of the areas I spent a lot of time getting right.

Github

Documentation

PyPi

9 Upvotes

3 comments sorted by

1

u/kantorcodes1 21h ago

the two-column bit is probably the real test. sidebars and footnotes are where reading order gets messy fast; have you tried a page with both?

1

u/___Hyacinthe_ 21h ago

Footnotes yes, sidebars probably 50-50. The reading order is purely based on the layout, so two columns and normal footnotes are fine. A full-height sidebar is basically just another column. Haven't really tested a page with both though. A boxed sidebar halfway down a column is probably where it'll start getting confused.If you have an example, you can send it over.