OCR with Tesseract in Java

Overview

Optical Character Recognition (OCR) using Tesseract in Java allows you to extract text from images. Tesseract is a powerful open-source OCR engine maintained by Google.

1. Setup and Dependencies

Maven Dependencies

<!-- pom.xml -->
<dependencies>
<!-- Tesseract OCR -->
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>5.8.0</version>
</dependency>
<!-- Image processing -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.9.4</version>
</dependency>
<!-- JavaFX for GUI (optional) -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
</dependencies>

Tesseract Installation

Windows:

  1. Download Tesseract from GitHub releases
  2. Install to C:\Program Files\Tesseract-OCR\
  3. Add to PATH or set TESSDATA_PREFIX environment variable

Linux (Ubuntu/Debian):

sudo apt-get update
sudo apt-get install tesseract-ocr
sudo apt-get install libtesseract-dev

macOS:

brew install tesseract
brew install tesseract-lang

2. Basic OCR Implementation

Simple Text Extraction

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import java.io.File;
public class BasicOCR {
public static String extractTextFromImage(String imagePath) {
try {
Tesseract tesseract = new Tesseract();
// Set tessdata path (where language data files are located)
tesseract.setDatapath("tessdata");
// Set language (default is English)
tesseract.setLanguage("eng");
// Perform OCR
String result = tesseract.doOCR(new File(imagePath));
return result;
} catch (TesseractException e) {
System.err.println("OCR Error: " + e.getMessage());
return null;
}
}
public static void main(String[] args) {
String imagePath = "sample.png";
String extractedText = extractTextFromImage(imagePath);
if (extractedText != null) {
System.out.println("Extracted Text:");
System.out.println(extractedText);
} else {
System.out.println("Failed to extract text from image.");
}
}
}

Advanced OCR Configuration

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.util.ImageHelper;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class AdvancedOCR {
private Tesseract tesseract;
public AdvancedOCR() {
initializeTesseract();
}
private void initializeTesseract() {
tesseract = new Tesseract();
// Basic configuration
tesseract.setDatapath("tessdata");
tesseract.setLanguage("eng");
// Advanced configuration
tesseract.setPageSegMode(6); // 6 = Uniform block of text
tesseract.setOcrEngineMode(1); // 1 = Neural nets LSTM engine
// Performance settings
tesseract.setTessVariable("preserve_interword_spaces", "1");
tesseract.setTessVariable("user_defined_dpi", "300");
}
public String extractText(String imagePath) throws TesseractException {
return tesseract.doOCR(new File(imagePath));
}
public String extractTextWithPreprocessing(String imagePath) throws Exception {
BufferedImage image = ImageIO.read(new File(imagePath));
// Preprocess image for better OCR results
BufferedImage processedImage = preprocessImage(image);
return tesseract.doOCR(processedImage);
}
private BufferedImage preprocessImage(BufferedImage image) {
// Convert to grayscale
BufferedImage grayscale = ImageHelper.convertImageToGrayscale(image);
// Increase contrast
BufferedImage highContrast = ImageHelper.convertImageToBinary(grayscale);
// Resize image if too small (minimum 300 DPI recommended)
if (highContrast.getWidth() < 600) {
double scale = 600.0 / highContrast.getWidth();
highContrast = ImageHelper.getScaledInstance(
highContrast, 
(int)(highContrast.getWidth() * scale),
(int)(highContrast.getHeight() * scale)
);
}
return highContrast;
}
// Method to get confidence scores
public void analyzeOCRConfidence(String imagePath) throws TesseractException {
File imageFile = new File(imagePath);
// Get OCR result with confidence information
String result = tesseract.doOCR(imageFile);
// Note: Tess4j doesn't directly provide confidence scores in current version
// You might need to use different approaches or libraries for confidence analysis
System.out.println("OCR Result:");
System.out.println(result);
}
public static void main(String[] args) {
try {
AdvancedOCR ocr = new AdvancedOCR();
String imagePath = "document.png";
String text = ocr.extractTextWithPreprocessing(imagePath);
System.out.println("Extracted Text:");
System.out.println(text);
} catch (Exception e) {
e.printStackTrace();
}
}
}

3. Image Preprocessing for Better OCR

Comprehensive Image Preprocessing

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import javax.imageio.ImageIO;
public class ImagePreprocessor {
public static BufferedImage preprocessForOCR(BufferedImage originalImage) {
BufferedImage processed = originalImage;
// Step 1: Convert to grayscale
processed = convertToGrayscale(processed);
// Step 2: Noise reduction
processed = reduceNoise(processed);
// Step 3: Enhance contrast
processed = enhanceContrast(processed);
// Step 4: Sharpen image
processed = sharpenImage(processed);
// Step 5: Deskew if needed
processed = deskewImage(processed);
// Step 6: Resize for better OCR (if image is too small)
processed = resizeImage(processed, 2.0); // Double the size
return processed;
}
public static BufferedImage convertToGrayscale(BufferedImage image) {
BufferedImage grayscale = new BufferedImage(
image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g = grayscale.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return grayscale;
}
public static BufferedImage reduceNoise(BufferedImage image) {
// Apply Gaussian blur for noise reduction
float[] matrix = {
1/16f, 2/16f, 1/16f,
2/16f, 4/16f, 2/16f,
1/16f, 2/16f, 1/16f
};
Kernel kernel = new Kernel(3, 3, matrix);
ConvolveOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
return op.filter(image, null);
}
public static BufferedImage enhanceContrast(BufferedImage image) {
// Simple contrast enhancement by stretching histogram
int width = image.getWidth();
int height = image.getHeight();
BufferedImage contrasted = new BufferedImage(width, height, image.getType());
int[] histogram = new int[256];
// Build histogram
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color color = new Color(image.getRGB(x, y));
int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
histogram[gray]++;
}
}
// Find min and max values (ignoring extremes)
int min = 0, max = 255;
for (int i = 0; i < 256; i++) {
if (histogram[i] > width * height * 0.001) { // Ignore extreme darks
min = i;
break;
}
}
for (int i = 255; i >= 0; i--) {
if (histogram[i] > width * height * 0.001) { // Ignore extreme brights
max = i;
break;
}
}
// Apply contrast stretch
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color color = new Color(image.getRGB(x, y));
int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
// Stretch contrast
int newGray = (gray - min) * 255 / (max - min);
newGray = Math.max(0, Math.min(255, newGray));
Color newColor = new Color(newGray, newGray, newGray);
contrasted.setRGB(x, y, newColor.getRGB());
}
}
return contrasted;
}
public static BufferedImage sharpenImage(BufferedImage image) {
// Sharpening kernel
float[] matrix = {
-1, -1, -1,
-1,  9, -1,
-1, -1, -1
};
Kernel kernel = new Kernel(3, 3, matrix);
ConvolveOp op = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
return op.filter(image, null);
}
public static BufferedImage deskewImage(BufferedImage image) {
// Simple deskewing by detecting text angle
// This is a simplified version - real deskewing is more complex
return image; // Implement proper deskewing as needed
}
public static BufferedImage resizeImage(BufferedImage image, double scale) {
int newWidth = (int) (image.getWidth() * scale);
int newHeight = (int) (image.getHeight() * scale);
Image scaled = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
BufferedImage resized = new BufferedImage(newWidth, newHeight, image.getType());
Graphics2D g2d = resized.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(scaled, 0, 0, null);
g2d.dispose();
return resized;
}
public static void saveImage(BufferedImage image, String outputPath) throws Exception {
File output = new File(outputPath);
ImageIO.write(image, "png", output);
}
public static void main(String[] args) {
try {
// Load original image
BufferedImage original = ImageIO.read(new File("input.jpg"));
// Preprocess image
BufferedImage processed = preprocessForOCR(original);
// Save processed image
saveImage(processed, "processed.png");
System.out.println("Image preprocessing completed.");
} catch (Exception e) {
e.printStackTrace();
}
}
}

4. Multi-language OCR

Supporting Multiple Languages

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class MultiLanguageOCR {
private Tesseract tesseract;
private Map<String, String> languageMap;
public MultiLanguageOCR() {
initializeTesseract();
initializeLanguages();
}
private void initializeTesseract() {
tesseract = new Tesseract();
tesseract.setDatapath("tessdata");
tesseract.setPageSegMode(6);
}
private void initializeLanguages() {
languageMap = new HashMap<>();
languageMap.put("english", "eng");
languageMap.put("spanish", "spa");
languageMap.put("french", "fra");
languageMap.put("german", "deu");
languageMap.put("chinese", "chi_sim");
languageMap.put("japanese", "jpn");
languageMap.put("korean", "kor");
languageMap.put("arabic", "ara");
languageMap.put("russian", "rus");
}
public String detectLanguage(String imagePath) throws TesseractException {
// Simple language detection by trying multiple languages
String bestLanguage = "eng";
int bestScore = 0;
for (String langCode : languageMap.values()) {
try {
tesseract.setLanguage(langCode);
String result = tesseract.doOCR(new File(imagePath));
// Simple scoring based on valid characters and word count
int score = calculateOCRScore(result);
if (score > bestScore) {
bestScore = score;
bestLanguage = langCode;
}
} catch (TesseractException e) {
// Language data might not be available
continue;
}
}
return bestLanguage;
}
private int calculateOCRScore(String text) {
if (text == null || text.trim().isEmpty()) {
return 0;
}
// Count words (simple whitespace splitting)
String[] words = text.trim().split("\\s+");
int wordCount = words.length;
// Count valid characters (alphanumeric and common punctuation)
int validChars = 0;
for (char c : text.toCharArray()) {
if (Character.isLetterOrDigit(c) || ".,!?;:-'\"()[]{} ".indexOf(c) >= 0) {
validChars++;
}
}
return wordCount * 10 + validChars;
}
public OCRResult extractText(String imagePath, String language) throws TesseractException {
String langCode = languageMap.getOrDefault(language.toLowerCase(), "eng");
tesseract.setLanguage(langCode);
long startTime = System.currentTimeMillis();
String text = tesseract.doOCR(new File(imagePath));
long endTime = System.currentTimeMillis();
return new OCRResult(text, langCode, endTime - startTime);
}
public OCRResult extractTextAutoLanguage(String imagePath) throws TesseractException {
String detectedLanguage = detectLanguage(imagePath);
return extractText(imagePath, getLanguageName(detectedLanguage));
}
private String getLanguageName(String langCode) {
for (Map.Entry<String, String> entry : languageMap.entrySet()) {
if (entry.getValue().equals(langCode)) {
return entry.getKey();
}
}
return "english";
}
public static class OCRResult {
private final String text;
private final String language;
private final long processingTime;
public OCRResult(String text, String language, long processingTime) {
this.text = text;
this.language = language;
this.processingTime = processingTime;
}
// Getters
public String getText() { return text; }
public String getLanguage() { return language; }
public long getProcessingTime() { return processingTime; }
@Override
public String toString() {
return String.format("Language: %s\nProcessing Time: %dms\nText:\n%s", 
language, processingTime, text);
}
}
public static void main(String[] args) {
try {
MultiLanguageOCR ocr = new MultiLanguageOCR();
String imagePath = "multi_language_document.png";
// Auto-detect language
OCRResult result = ocr.extractTextAutoLanguage(imagePath);
System.out.println("Auto-detected Result:");
System.out.println(result);
// Extract with specific language
OCRResult frenchResult = ocr.extractText(imagePath, "french");
System.out.println("\nFrench-specific Result:");
System.out.println(frenchResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}

5. Batch Processing and PDF OCR

Batch Image Processing

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import java.io.*;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class BatchOCRProcessor {
private Tesseract tesseract;
private ExecutorService executorService;
public BatchOCRProcessor() {
initializeTesseract();
executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
}
private void initializeTesseract() {
tesseract = new Tesseract();
tesseract.setDatapath("tessdata");
tesseract.setLanguage("eng");
tesseract.setPageSegMode(6);
}
public List<OCRJobResult> processDirectory(String directoryPath) throws Exception {
List<Path> imageFiles = findImageFiles(directoryPath);
List<Future<OCRJobResult>> futures = new ArrayList<>();
for (Path imageFile : imageFiles) {
Callable<OCRJobResult> task = () -> processSingleFile(imageFile);
futures.add(executorService.submit(task));
}
List<OCRJobResult> results = new ArrayList<>();
for (Future<OCRJobResult> future : futures) {
try {
results.add(future.get());
} catch (Exception e) {
System.err.println("Error processing file: " + e.getMessage());
}
}
return results;
}
private List<Path> findImageFiles(String directoryPath) throws IOException {
List<Path> imageFiles = new ArrayList<>();
Files.walk(Paths.get(directoryPath))
.filter(path -> {
String fileName = path.getFileName().toString().toLowerCase();
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") ||
fileName.endsWith(".png") || fileName.endsWith(".tiff") ||
fileName.endsWith(".bmp") || fileName.endsWith(".gif");
})
.forEach(imageFiles::add);
return imageFiles;
}
private OCRJobResult processSingleFile(Path imageFile) {
try {
long startTime = System.currentTimeMillis();
String text = tesseract.doOCR(imageFile.toFile());
long endTime = System.currentTimeMillis();
return new OCRJobResult(
imageFile.getFileName().toString(),
text,
endTime - startTime,
true,
null
);
} catch (TesseractException e) {
return new OCRJobResult(
imageFile.getFileName().toString(),
"",
0,
false,
e.getMessage()
);
}
}
public void exportResults(List<OCRJobResult> results, String outputDir) throws IOException {
Path outputPath = Paths.get(outputDir);
Files.createDirectories(outputPath);
for (OCRJobResult result : results) {
if (result.isSuccess()) {
String outputFileName = result.getFileName().replaceAll("\\.[^.]*$", "") + ".txt";
Path outputFile = outputPath.resolve(outputFileName);
Files.write(outputFile, result.getText().getBytes());
}
}
// Create summary report
createSummaryReport(results, outputPath.resolve("ocr_summary.csv"));
}
private void createSummaryReport(List<OCRJobResult> results, Path summaryPath) throws IOException {
StringBuilder csv = new StringBuilder();
csv.append("File Name,Success,Processing Time (ms),Text Length,Error\n");
for (OCRJobResult result : results) {
csv.append(String.format("\"%s\",%s,%d,%d,\"%s\"\n",
result.getFileName(),
result.isSuccess(),
result.getProcessingTime(),
result.getText().length(),
result.getError() != null ? result.getError() : ""
));
}
Files.write(summaryPath, csv.toString().getBytes());
}
public void shutdown() {
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
public static class OCRJobResult {
private final String fileName;
private final String text;
private final long processingTime;
private final boolean success;
private final String error;
public OCRJobResult(String fileName, String text, long processingTime, 
boolean success, String error) {
this.fileName = fileName;
this.text = text;
this.processingTime = processingTime;
this.success = success;
this.error = error;
}
// Getters
public String getFileName() { return fileName; }
public String getText() { return text; }
public long getProcessingTime() { return processingTime; }
public boolean isSuccess() { return success; }
public String getError() { return error; }
}
public static void main(String[] args) {
BatchOCRProcessor processor = null;
try {
processor = new BatchOCRProcessor();
String inputDirectory = "images/";
String outputDirectory = "ocr_results/";
System.out.println("Starting batch OCR processing...");
List<OCRJobResult> results = processor.processDirectory(inputDirectory);
System.out.println("Exporting results...");
processor.exportResults(results, outputDirectory);
// Print summary
long totalFiles = results.size();
long successfulFiles = results.stream().filter(OCRJobResult::isSuccess).count();
long totalProcessingTime = results.stream().mapToLong(OCRJobResult::getProcessingTime).sum();
System.out.printf("Batch Processing Complete:%n");
System.out.printf("Total Files: %d%n", totalFiles);
System.out.printf("Successful: %d%n", successfulFiles);
System.out.printf("Failed: %d%n", totalFiles - successfulFiles);
System.out.printf("Total Processing Time: %dms%n", totalProcessingTime);
System.out.printf("Average Time per File: %.2fms%n", 
(double) totalProcessingTime / totalFiles);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (processor != null) {
processor.shutdown();
}
}
}
}

6. JavaFX OCR Application

GUI OCR Application

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import java.io.File;
public class OCRGUIApplication extends Application {
private Tesseract tesseract;
private TextArea resultTextArea;
private ImageView imageView;
private Label statusLabel;
private File currentImageFile;
@Override
public void start(Stage primaryStage) {
initializeTesseract();
setupUI(primaryStage);
}
private void initializeTesseract() {
tesseract = new Tesseract();
tesseract.setDatapath("tessdata");
tesseract.setLanguage("eng");
}
private void setupUI(Stage stage) {
// Create UI components
BorderPane root = new BorderPane();
root.setPadding(new Insets(10));
// Top menu
MenuBar menuBar = createMenuBar(stage);
// Image display
imageView = new ImageView();
imageView.setFitWidth(400);
imageView.setFitHeight(300);
imageView.setPreserveRatio(true);
VBox imageBox = new VBox(10, new Label("Selected Image:"), imageView);
imageBox.setPadding(new Insets(10));
// Result area
resultTextArea = new TextArea();
resultTextArea.setPromptText("Extracted text will appear here...");
resultTextArea.setWrapText(true);
VBox resultBox = new VBox(10, new Label("Extracted Text:"), resultTextArea);
resultBox.setPadding(new Insets(10));
// Control buttons
Button extractButton = new Button("Extract Text");
extractButton.setOnAction(e -> extractText());
Button clearButton = new Button("Clear");
clearButton.setOnAction(e -> clearResults());
HBox buttonBox = new HBox(10, extractButton, clearButton);
buttonBox.setPadding(new Insets(10));
// Status bar
statusLabel = new Label("Ready");
statusLabel.setPadding(new Insets(5));
// Layout
HBox contentBox = new HBox(20, imageBox, resultBox);
VBox mainBox = new VBox(10, menuBar, contentBox, buttonBox, statusLabel);
root.setCenter(mainBox);
Scene scene = new Scene(root, 900, 600);
stage.setTitle("OCR Text Extraction Tool");
stage.setScene(scene);
stage.show();
}
private MenuBar createMenuBar(Stage stage) {
MenuBar menuBar = new MenuBar();
// File menu
Menu fileMenu = new Menu("File");
MenuItem openItem = new MenuItem("Open Image");
openItem.setOnAction(e -> openImage(stage));
MenuItem saveItem = new MenuItem("Save Text");
saveItem.setOnAction(e -> saveText());
MenuItem exitItem = new MenuItem("Exit");
exitItem.setOnAction(e -> stage.close());
fileMenu.getItems().addAll(openItem, new SeparatorMenuItem(), saveItem, exitItem);
// Language menu
Menu languageMenu = new Menu("Language");
RadioMenuItem englishItem = new RadioMenuItem("English");
englishItem.setSelected(true);
englishItem.setOnAction(e -> tesseract.setLanguage("eng"));
RadioMenuItem spanishItem = new RadioMenuItem("Spanish");
spanishItem.setOnAction(e -> tesseract.setLanguage("spa"));
RadioMenuItem frenchItem = new RadioMenuItem("French");
frenchItem.setOnAction(e -> tesseract.setLanguage("fra"));
ToggleGroup languageGroup = new ToggleGroup();
englishItem.setToggleGroup(languageGroup);
spanishItem.setToggleGroup(languageGroup);
frenchItem.setToggleGroup(languageGroup);
languageMenu.getItems().addAll(englishItem, spanishItem, frenchItem);
menuBar.getMenus().addAll(fileMenu, languageMenu);
return menuBar;
}
private void openImage(Stage stage) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Image File");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp"),
new FileChooser.ExtensionFilter("All Files", "*.*")
);
File file = fileChooser.showOpenDialog(stage);
if (file != null) {
currentImageFile = file;
displayImage(file);
statusLabel.setText("Image loaded: " + file.getName());
}
}
private void displayImage(File file) {
try {
Image image = new Image(file.toURI().toString());
imageView.setImage(image);
} catch (Exception e) {
showAlert("Error", "Could not load image: " + e.getMessage());
}
}
private void extractText() {
if (currentImageFile == null) {
showAlert("Warning", "Please select an image first.");
return;
}
try {
statusLabel.setText("Extracting text...");
// Run OCR in background thread
new Thread(() -> {
try {
String extractedText = tesseract.doOCR(currentImageFile);
// Update UI on JavaFX thread
javafx.application.Platform.runLater(() -> {
resultTextArea.setText(extractedText);
statusLabel.setText("Text extraction completed successfully.");
});
} catch (TesseractException e) {
javafx.application.Platform.runLater(() -> {
showAlert("OCR Error", "Failed to extract text: " + e.getMessage());
statusLabel.setText("Text extraction failed.");
});
}
}).start();
} catch (Exception e) {
showAlert("Error", "Unexpected error: " + e.getMessage());
}
}
private void clearResults() {
resultTextArea.clear();
imageView.setImage(null);
currentImageFile = null;
statusLabel.setText("Ready");
}
private void saveText() {
if (resultTextArea.getText().isEmpty()) {
showAlert("Warning", "No text to save.");
return;
}
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Save Text");
fileChooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("Text Files", "*.txt")
);
File file = fileChooser.showSaveDialog(resultTextArea.getScene().getWindow());
if (file != null) {
try {
java.nio.file.Files.write(file.toPath(), resultTextArea.getText().getBytes());
statusLabel.setText("Text saved to: " + file.getName());
} catch (Exception e) {
showAlert("Error", "Could not save file: " + e.getMessage());
}
}
}
private void showAlert(String title, String message) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
@Override
public void stop() {
// Cleanup resources if needed
}
public static void main(String[] args) {
launch(args);
}
}

Key Features Covered:

  1. Basic OCR Setup - Tesseract configuration and simple text extraction
  2. Image Preprocessing - Techniques to improve OCR accuracy
  3. Multi-language Support - Working with different languages
  4. Batch Processing - Processing multiple files efficiently
  5. GUI Application - User-friendly OCR tool with JavaFX
  6. Performance Optimization - Threading and efficient processing

This comprehensive OCR implementation provides everything needed to integrate text recognition capabilities into Java applications, from basic usage to advanced features like multi-language support and batch processing.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper