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 order | OneOCR alone | With the second pass |
|---|---|---|
| Gujarati, character error rate | 100% | 3–8% |
| Latin on the same pages | 1.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.
Five repositories
Each one builds and publishes on its own. Use the CLI, or take the binding and build your own tool on it.
cli →
The 1ocr command. Images, PDFs, folders, the layout export and a small GUI.
api →
The FFM binding to oneocr.dll, with arena-scoped native memory.
tesseract →
The optional second pass — an FFM binding to Tesseract 5 with script identification.
io.github.oneocr:oneocr-tesseractxhtml_controls_js →
The viewer controls, written in Java and compiled to JavaScript by TeaVM.
io.github.oneocr:oneocr-xhtml_controls_jssemantic_xhtml →
The CSS and JS that every generated document links, served from this domain.
oneocr.github.io/semantic_xhtml/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.