Implementing OCR in Android and iOS apps with open-source SDKs
Tesseract extracts text from images without sending them to a cloud service. This guide shows Android model installation and OCR resource management, then explains the installation limitations of the legacy iOS wrapper used in the original article.
Introduction to OCR in mobile apps
Optical Character Recognition (OCR) technology extracts text from digital images. Implementing OCR in mobile apps opens up possibilities for document scanning, text extraction, and improved user experiences by converting images into editable text.
Prerequisites
Before integrating OCR in your mobile apps, ensure you meet these requirements:
- Android: API
21or later, with an Android SDK and a compatible Gradle project. - iOS: full Xcode and an iOS SDK to check the legacy wrapper’s device and simulator architectures. A successful macOS build of a different wrapper cannot establish iOS compatibility.
- Language data compatible with the engine bundled by each wrapper. The two wrappers below use different engine generations.
- Private app storage for Android model files, without shared-storage permissions.
Overview of open-source OCR SDKs
Tesseract4Android packages the engine for Android. TesseractOCRiOS is an older Objective-C wrapper with separately bundled native libraries. A wrapper’s version number is not the Tesseract engine version; use the wrapper’s documented engine and language data combination.
Setting up Tesseract OCR in Android
To integrate Tesseract OCR into your Android app, follow these steps:
-
Add JitPack to
dependencyResolutionManagement.repositoriesinsettings.gradle:dependencyResolutionManagement { repositories { google() mavenCentral() maven { url 'https://jitpack.io' } } }Add the pinned Tesseract4Android
4.8.0dependency to your app’sbuild.gradle:dependencies { implementation 'cz.adaptech.tesseract4android:tesseract4android:4.8.0' // For multi-threaded support, use: // implementation 'cz.adaptech.tesseract4android:tesseract4android-openmp:4.8.0' } -
Include the trained data files:
Download
eng.traineddatafrom the pinned Tesseract4.0.0data release and place it atapp/src/main/assets/tessdata/eng.traineddata. The linked manager copies it to private storage before initialization. Assets inside an APK are not filesystem paths that Tesseract can open directly.
Implementing OCR in an Android app
Use the complete
OCRManager.java class in the live Android OCR guide
in your app’s package. That section includes the model installation and lifecycle contract for
single-image and repeated recognition on one background worker.
Setting up Tesseract OCR in iOS
The original TesseractOCRiOS pin, 5.0.1, is registered in CocoaPods, but its
podspec
points to a Git tag that is absent from the upstream repository. A registration alone does not
make the package installable.
The available 4.0.0 source tag provides a
retrievable legacy reference. It bundles Tesseract 3.03-rc1, not a current Tesseract engine.
The following setup is for evaluating that legacy implementation. Its compatibility with current
Xcode, iOS devices, and simulators has not been verified for this guide; this is a prerequisite
before adopting it in an app.
-
Add TesseractOCRiOS via CocoaPods by updating your Podfile:
platform :ios, '9.0' use_frameworks! target 'YourApp' do pod 'TesseractOCRiOS', '4.0.0' end -
Install the dependencies by running:
pod install -
Add compatible legacy language data to a real
tessdatadirectory in the app bundle, includingtessdata/eng.traineddata. Preserve the directory when adding it to the app target’s resources. Follow the wrapper’s installation guide for its Tesseract3.03data requirements; do not substitute the Android model files above.
Build both the intended device and simulator targets in full Xcode before proceeding. CocoaPods dependency resolution alone does not check native library architectures or recognition behavior.
Implementing OCR in an iOS app
This Objective-C example uses the legacy wrapper’s API. Keep the manager on one serial background
queue, and handle a nil initialization or recognition result as a failure.
#import <Foundation/Foundation.h>
#import <TesseractOCR/TesseractOCR.h>
#import <UIKit/UIKit.h>
@interface OCRManager : NSObject
@property (nonatomic, strong, readonly) G8Tesseract *tesseract;
- (nullable instancetype)init;
- (nullable NSString *)extractTextFromImage:(UIImage *)image;
@end
@implementation OCRManager
- (instancetype)init {
self = [super init];
if (self) {
_tesseract = [[G8Tesseract alloc] initWithLanguage:@"eng"];
if (_tesseract == nil) return nil;
_tesseract.engineMode = G8OCREngineModeTesseractOnly;
_tesseract.pageSegmentationMode = G8PageSegmentationModeAuto;
}
return self;
}
- (NSString *)extractTextFromImage:(UIImage *)image {
self.tesseract.image = [image g8_blackAndWhite];
if (![self.tesseract recognize]) return nil;
return self.tesseract.recognizedText;
}
@end
ARC releases the manager and its native wrapper when you drop the final reference. Enclose repeated recognition work in an autorelease pool on the worker queue, and release the manager only after its queued work has finished. The code and installation reference above still require an iOS build and a real image-recognition check before this part of the guide is considered verified.
Tips for optimizing OCR performance
To achieve optimal OCR performance in your mobile apps, consider the following best practices:
-
Image Preprocessing:
- Convert images to grayscale.
- Apply adaptive thresholding or binarization.
- Reduce noise using filters such as Gaussian blur.
- Keep text in focus and large enough in the image; changing DPI metadata cannot restore detail.
-
Resource Management:
- Reuse
TessBaseAPIorG8Tesseractinstances if processing multiple images. - Release resources properly once OCR processing is complete.
- Cache results for frequently processed images to improve performance.
- Reuse
-
Threading Considerations:
- Serialize initialization, recognition, and cleanup on one worker. Do not share an instance between simultaneous recognition calls.
- Run all OCR tasks on background threads to prevent UI blocking.
-
Performance Optimization:
- Choose appropriate page segmentation modes for your specific use case.
- Limit recognition to expected character sets to reduce processing time.
Conclusion
On Android, copy language data before initializing the engine and release native resources after the final OCR task. For iOS, first resolve the legacy wrapper’s native build prerequisites or select and validate another open-source Tesseract integration for your target devices.
For advanced file processing, including image processing and document processing, consider exploring Transloadit's services.
