Tess4J on Mac and Linux, tested on 55 scans
2.6x
less CPU with one engine
Unable to load library: install Tesseract
Ubuntu without Tesseract:
java.lang.UnsatisfiedLinkError: Unable to load library 'tesseract':
libtesseract.so: cannot open shared object file: No such file or directory
The jar carries Tesseract for Windows only. On Mac and Linux, install it, and Tess4J finds it:
| System | Install | Found |
|---|---|---|
| Ubuntu 26.04.1 | sudo apt-get install tesseract-ocr |
libtesseract.so.5 |
| Mac, Apple Silicon | brew install tesseract |
/opt/homebrew/lib |
Then set the models folder
With Tesseract in place, the next run can fail like this:
Error opening data file ./eng.traineddata
java.lang.IllegalArgumentException: Specified language data does not exist.
Tess4J looks in TESSDATA_PREFIX, else in the folder you
run from. Set the path, as in the code below. On Ubuntu it is
/usr/share/tesseract-ocr/5/tessdata.
The jar also carries eng.traineddata, the same file as
Homebrew's. To use it, copy it out first:
tess.setDatapath(LoadLibs.extractTessResources("tessdata").getPath());
The code, run on 55 scans
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.21.0</version>
</dependency>
import java.io.File;
import net.sourceforge.tess4j.Tesseract;
public class Ocr {
public static void main(String[] args) throws Exception {
Tesseract tess = new Tesseract();
tess.setDatapath("/opt/homebrew/share/tessdata");
tess.setLanguage("eng");
tess.setPageSegMode(3);
tess.setVariable("user_defined_dpi", "300");
System.out.println(tess.doOCR(new File("scan.jpg")));
}
}
Run as printed, it wrote the tesseract command's text on
55 of 55 scans.
Set psm 3 to match the command
Without setPageSegMode, Tesseract's own default applies:
psm 6, the page as one block. The command uses psm 3, which finds the
layout first.
9 of 55 scans, the command's text without it
13,839 words found, 19 fewer
My scans have one column. I did not test pages with more.
Same text, 23% more CPU
55 of 55 scans, the same text
13,858 of 14,693 words found, both
| Job | Command | Tess4J |
|---|---|---|
| 55 full pages | 147.3 s | 181.7 s |
| 259 line images | 50.9 s | 52.8 s |
Tess4J writes each image as a PNG in memory before Tesseract reads it. In a profile run, that took 34.4 s of 191.0 s.
Many small images: keep one engine
doOCR loads the model again on every call. Keep one
engine with the low-level API instead:
TessBaseAPI api = TessAPI1.TessBaseAPICreate();
TessAPI1.TessBaseAPIInit3(api, "/opt/homebrew/share/tessdata", "eng");
TessAPI1.TessBaseAPISetPageSegMode(api, 7);
TessAPI1.TessBaseAPISetVariable(api, "user_defined_dpi", "300");
for (File f : files) {
BufferedImage img = ImageIO.read(f); // 8-bit gray
ByteBuffer px = ImageIOHelper.convertImageData(img);
TessAPI1.TessBaseAPISetImage(api, px, img.getWidth(), img.getHeight(), 1, img.getWidth());
Pointer text = TessAPI1.TessBaseAPIGetUTF8Text(api);
System.out.print(text.getString(0));
TessAPI1.TessDeleteText(text);
}
TessAPI1.TessBaseAPIDelete(api);
20.2 s for 259 lines, not 52.8 s
All 259 lines, the command's text
This version takes 8-bit gray images, like my line crops. I did not test it on color.
PDFs work, at twice the CPU
Pass a PDF to doOCR and Tess4J renders each page at 300
dpi with PDFBox. I made a 10-page PDF from the scans.
1,878 of 1,955 words, as from the JPEGs
6.8 s of CPU a page, not 3.3 s
It deleted its temporary files.
How I tested it
- Pages: 55 proofread Wikisource scans from 11 printed books, JPEG, 1,920 pixels wide, no dpi in the file. The same set as Tesseract in Docker.
- Score: true words found in order, with the scorer of the tessdata test.
- Apple Silicon Mac, OpenJDK 21, Maven 3.9.16, Tess4J 5.21.0, Homebrew Tesseract 5.5.4, tessdata_fast English.
- Ubuntu: Docker, eclipse-temurin:21-jdk on arm64, apt-get as root with --no-install-recommends.
- Time is CPU time of the whole process tree, JVM start included, on the Mac's efficiency cores. Pages: median of 3 rounds. Lines and PDF: 1 round.
- Line images: the 259 PNG crops of the tesserocr test, psm 7.
What I did not test
- Windows, Intel Macs, x86-64 Linux, and older Tess4J.
- Threads, wall time, and color images on the one-engine code.
- Other languages, tessdata_best, and photos.
Sources
Two ways to skip the work
Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.
Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.
Questions people ask
Do I need libtesseract-dev?
Not on Ubuntu 26.04.1. The tesseract-ocr package brings libtesseract.so.5, and Tess4J 5.21.0 loaded it. I did not test older Ubuntu or Debian releases.
Which Tesseract does Tess4J use?
On Mac and Linux, the one you installed. Tess4J reported 5.5.4 from Homebrew and 5.5.0 from Ubuntu. The jar carries a Tesseract only for 64-bit Windows.
Does it give the same text as the command?
Yes, byte for byte on 55 of 55 scans, with the same Tesseract, the same model, psm 3 and 300 dpi on both. Every round gave the same text.