oneocr

Java · FFM · Windows 11

Windows 11 already has an OCR engine. This one calls it from Java.

The Snipping Tool ships an undocumented ~50 MB Microsoft OCR model. oneocr binds it through the JDK's Foreign Function & Memory API — no JNI, nothing to compile — and adds 1ocr, a command line tool for images, PDFs and whole folders.

# a page, and everything it can tell you about it
1ocr page.png
#   -> page.png.oneocr.txt  .json  .svg  .xhtml

# a PDF, with the reading order recovered
1ocr pdf order.pdf --layout

# a whole tree, resumable
1ocr folder ./scans -r

One page, six files

Four are written by default, beside the input. The layout export and the second pass are asked for. Nothing is overwritten, and the originals are never modified.

.txt  Plain text

The recognised text, in the order the engine reported it.

.json  Compact JSON

Every word with its bounding box, confidence and index. The machine-readable record.

.svg  Vector overlay

Words placed at their true page coordinates, over the source image.

.xhtml  Semantic XHTML →

A browser-renderable document with real elements per segment and per word. Toggle word boxes, confidence colouring and the precise SVG layer. Open the demo.

.layout.html  Layout export →

Reading order recovered: columns become tables, split lines are rejoined, alignment detected.

+tesseract  Second pass

A parallel set of the same four, where a second engine re-read the lines OneOCR could not.

Line order is not reading order

The engine reports lines in its own sequence. On a single column of prose that is fine. On anything set in two columns it interleaves them, and a cause title comes out unusable.

As the engine reports it

Siva Vallabhaneni
Petitioner
Union of India
Respondent

With --layout

Siva Vallabhaneni     Petitioner
Union of India        Respondent

Structure is recovered by recursive X-Y cutting over the line boxes: parallel columns become a table, one printed line detected as two boxes is rejoined, and left, centre and right alignment is detected per block. Thresholds are scale-free — expressed in multiples of the page's own median line height — so the same numbers hold at any DPI.

Measured on a real 83-page legal notice: 145 orphaned fragments rejoined and its table of contents unscrambled. 1ocr layout <file>.oneocr.xhtml re-renders from the saved boxes with no second OCR pass, which makes threshold tuning a sub-second loop.

Where the engine fails silently, a second engine reads

OneOCR handles Latin, Devanagari and Tamil well. On the other Indic scripts it does not error — it returns another script, or Latin gibberish, while its page-level confidence still looks healthy, because the lines it could not read are simply dropped from the average.

On a 25-page bilingual court orderOneOCR aloneWith the second pass
Gujarati, character error rate100%3–8%
Latin on the same pages1.4%0.4%

Latin improves, because some of the flagged lines were ones where OneOCR had mangled its own English alongside the Gujarati. Only the lines a per-line confidence guard flags are re-read; the script is identified by letting candidate models compete on confidence, and the results are spliced back into OneOCR's own geometry.

# candidates are always explicit — there is no default set
1ocr page.png --tesseract --tess-candidates guj,hin
1ocr pdf report.pdf --tesseract --tess-lang guj   # skip probing

Needs Tesseract 5.4+. Language models are downloaded on first use and cached; nothing is bundled.

Install

JDK 22+, where FFM is final. JDK 21 works with --enable-preview. Windows 11 for now.

As a library

<dependency>
  <groupId>io.github.oneocr</groupId>
  <artifactId>oneocr-api</artifactId>
  <version>2.0</version>
</dependency>

As a command

# build the shaded jar, then run it
git clone https://github.com/oneocr/api      && (cd api      && mvn install)
git clone https://github.com/oneocr/tesseract && (cd tesseract && mvn install)
git clone https://github.com/oneocr/cli      && (cd cli      && mvn package)

java --enable-native-access=ALL-UNNAMED -jar cli/target/1ocr-2.0.jar page.png

The native libraries are not distributed here. oneocr.dll, oneocr.onemodel, onnxruntime.dll and opencv_world*.dll are Microsoft components that ship with Windows, and they are not ours to redistribute.

Take them from your own Windows installation and place them in api/src/main/resources/natives/ before building. The b1tg project documents where they live.