chi_sim.traineddata),命令行工具。jai_imageio (TIFF 支援)、swingx (OS 判斷)。<dependency>
<groupId>javax.media.jai</groupId>
<artifactId>jai_imageio</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.swinglabs.swingx</groupId>
<artifactId>swingx</artifactId>
<version>1.6.5-1</version>
</dependency>
tesseract.exe 命令行:tesseract input.tif output -l chi_sim。output.txt,返回識別文本。public class ImageIOHelper {
public static File createImage(File imageFile, String formatName) throws IOException {
// 1. 獲取對應格式的 ImageReader
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(formatName);
ImageReader reader = readers.next();
ImageInputStream iis = ImageIO.createImageInputStream(imageFile);
reader.setInput(iis);
// 2. 讀取圖像數據
BufferedImage bi = reader.read(0);
IIOImage image = new IIOImage(bi, null, reader.getImageMetadata(0));
// 3. 配置 TIFF 寫入參數:無壓縮
TIFFImageWriteParam tiffParam = new TIFFImageWriteParam(Locale.CHINESE);
tiffParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
// 4. 寫入臨時 TIFF 文件
File tempFile = tempImageFile(imageFile); // 同目錄下 xxx0.tif
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
ImageWriter writer = writers.next();
ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);
writer.setOutput(ios);
writer.write(reader.getStreamMetadata(), image, tiffParam);
// 5. 釋放資源
ios.close(); writer.dispose(); reader.dispose(); iis.close();
return tempFile;
}
private static File tempImageFile(File original) {
String path = original.getAbsolutePath();
return new File(path.substring(0, path.lastIndexOf('.')) + "0.tif");
}
}
public class OCR {
private final String tessPath = "C:/Program Files (x86)/Tesseract-OCR"; // 安裝路徑
private final String LANG = "chi_sim"; // 中文簡體
public String recognizeText(File imageFile, String format) throws Exception {
File tiffFile = ImageIOHelper.createImage(imageFile, format);
File outputBase = new File(imageFile.getParent(), "ocr_output");
// 構建命令
List cmd = new ArrayList<>();
cmd.add(OS.isWindowsXP() ? tessPath + "/tesseract.exe" : "tesseract");
cmd.add(tiffFile.getName());
cmd.add(outputBase.getName());
cmd.add("-l"); cmd.add(LANG);
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(imageFile.getParentFile());
pb.redirectErrorStream(true);
Process process = pb.start();
int exitCode = process.waitFor();
// 清理臨時 TIFF
tiffFile.delete();
if (exitCode == 0) {
File txtFile = new File(outputBase.getAbsolutePath() + ".txt");
String text = Files.readString(txtFile.toPath(), StandardCharsets.UTF_8);
txtFile.delete();
return text.trim();
} else {
throw new RuntimeException("Tesseract 執行失敗,退出碼: " + exitCode);
}
}
}
public class OcrTest {
public static void main(String[] args) {
File img = new File("C:/temp/OCRcode/4.png"); // 驗證碼圖片
try {
String text = new OCR().recognizeText(img, "png");
System.out.println("識別結果: " + text);
} catch (Exception e) {
e.printStackTrace();
}
}
}
| 環節 | 說明 |
|---|---|
| 為何轉 TIFF | Tesseract 3.x 內部使用 Leptonica 庫,對 TIFF 支援最完善(無損、多頁、條帶/瓦片) |
| 禁用壓縮 | MODE_DISABLED 避免壓縮伪影影響識別率 |
| 語言包 | chi_sim.traineddata 需放入 tessdata/ 目錄,安裝時勾選或手動下載 |
| 進程調用 | ProcessBuilder 替代 Runtime.exec(),支援工作目錄、環境變量、錯誤流合併 |
| 臨時文件清理 | 識別完成後立即刪除 .tif 和 .txt,避免磁盤佔用 |
--oem 1 (LSTM only),Java 調用方式相同。ITesseract instance = new Tesseract(); instance.setDatapath("tessdata"); String result = instance.doOCR(bufferedImage);JavaCV) 顯著提升驗證碼識別率。GenericObjectPool) 管理 ITesseract 實例。本文展示了 Java 調用 Tesseract 3.01 命令行實現中文 OCR 的完整流程:圖像轉 TIFF → 進程調用 → 結果解析。雖然可行,但強烈建議遷移至 Tess4J + Tesseract 4+/5+,獲得更高識別率、更簡潔 API、更好併發支援。驗證碼識別屬於對抗性場景,單純 OCR 難以長期有效,需結合深度學習專用模型(如 CRNN、Transformer)持續迭代。