Skip to content

Commit

Permalink
First release
Browse files Browse the repository at this point in the history
  • Loading branch information
ldiqual committed Sep 24, 2012
0 parents commit c515b25
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 0 deletions.
24 changes: 24 additions & 0 deletions Classes/Tesseract.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Tesseract.h
// TesseractTest
//
// Created by Loïs Di Qual on 24/09/12.
// Copyright (c) 2012 Loïs Di Qual. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Tesseract : NSObject {
NSString* _dataPath;
NSString* _language;
NSMutableDictionary* _variables;
}

- (id)initWithDataPath:(NSString *)dataPath language:(NSString *)language;
- (void)setVariableValue:(NSString *)value forKey:(NSString *)key;
- (void)setImage:(UIImage *)image;
- (BOOL)setLanguage:(NSString *)language;
- (BOOL)recognize;
- (NSString *)recognizedText;

@end
146 changes: 146 additions & 0 deletions Classes/Tesseract.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//
// Tesseract.m
// TesseractTest
//
// Created by Loïs Di Qual on 24/09/12.
// Copyright (c) 2012 Loïs Di Qual. All rights reserved.
//

#import "Tesseract.h"

#import "baseapi.h"
#import "environ.h"
#import "pix.h"

namespace tesseract {
class TessBaseAPI;
};

@interface Tesseract () {
tesseract::TessBaseAPI* _tesseract;
uint32_t* _pixels;
}

@end

@implementation Tesseract

- (id)initWithDataPath:(NSString *)dataPath language:(NSString *)language {
self = [super init];
if (self) {
_dataPath = dataPath;
_language = language;
_variables = [[NSMutableDictionary alloc] init];

[self copyDataToDocumentsDirectory];
_tesseract = new tesseract::TessBaseAPI();

BOOL success = [self initEngine];
if (!success) {
return NO;
}
}
return self;
}

- (BOOL)initEngine {
int returnCode = _tesseract->Init([_dataPath UTF8String], [_language UTF8String]);
return (returnCode == 0) ? YES : NO;
}

- (void)copyDataToDocumentsDirectory {

// Useful paths
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = ([documentPaths count] > 0) ? [documentPaths objectAtIndex:0] : nil;
NSString *dataPath = [documentPath stringByAppendingPathComponent:_dataPath];

// Copy data in Doc Directory
if (![fileManager fileExistsAtPath:dataPath]) {
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *tessdataPath = [bundlePath stringByAppendingPathComponent:_dataPath];
if (tessdataPath) {
[fileManager copyItemAtPath:tessdataPath toPath:dataPath error:nil];
}
}

setenv("TESSDATA_PREFIX", [[documentPath stringByAppendingString:@"/"] UTF8String], 1);
}

- (void)setVariableValue:(NSString *)value forKey:(NSString *)key {
/*
* Example:
* _tesseract->SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
* _tesseract->SetVariable("language_model_penalty_non_freq_dict_word", "0");
* _tesseract->SetVariable("language_model_penalty_non_dict_word ", "0");
*/

[_variables setValue:value forKey:key];
_tesseract->SetVariable([key UTF8String], [value UTF8String]);
}

- (void)loadVariables {
for (NSString* key in _variables) {
NSString* value = [_variables objectForKey:key];
_tesseract->SetVariable([key UTF8String], [value UTF8String]);
}
}

- (BOOL)setLanguage:(NSString *)language {
_language = language;
int returnCode = [self initEngine];
if (returnCode != 0) return NO;

/*
* "WARNING: On changing languages, all Tesseract parameters
* are reset back to their default values."
*/
[self loadVariables];
return YES;
}

- (BOOL)recognize {
int returnCode = _tesseract->Recognize(NULL);
return (returnCode == 0) ? YES : NO;
}

- (NSString *)recognizedText {
char* utf8Text = _tesseract->GetUTF8Text();
return [NSString stringWithUTF8String:utf8Text];
}

- (void)setImage:(UIImage *)image
{
free(_pixels);

CGSize size = [image size];
int width = size.width;
int height = size.height;

if (width <= 0 || height <= 0) {
return;
}

_pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));

// Clear the pixels so any transparency is preserved
memset(_pixels, 0, width * height * sizeof(uint32_t));

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

// Create a context with RGBA _pixels
CGContextRef context = CGBitmapContextCreate(_pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

// Paint the bitmap to our context which will fill in the _pixels array
CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]);

// We're done with the context and color space
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);

_tesseract->SetImage((const unsigned char *) _pixels, width, height, sizeof(uint32_t), width * sizeof(uint32_t));
}

@end
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
Tesseract for iOS
=================


About
-----

Tesseract-ios is an Objective-C wrapper for [Tesseract OCR](http://code.google.com/p/tesseract-ocr/).


Requirements
------------

- iOS SDK 6.0, iOS 5.0+ (there is no support for armv6)
- Tesseract and Leptonica libraries from the [tesseract-ios-lib](https://github.com/ldiqual/tesseract-ios-lib) repo.


Usage
-----

Here is the default workflow to extract text from an image:

- Instantiate Tesseract with data path and language
- Set variables (character set, …)
- Set the image to analyze
- Start recognition
- Get recognized text


Code Sample
-----------

#import "Tesseract.h"

Tesseract* tesseract = [[Tesseract alloc] initWithDataPath:@"tessdata" language:@"eng"];
[tesseract setVariableValue:@"tessedit_char_whitelist" forKey:@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"];
[tesseract setImage:[UIImage imageNamed:@"image_sample.jpg"]];
[tesseract recognize];

NSLog(@"%@", [tesseract recognizedText]);


Method reference
----------------

### -initWithDataPath:language: ###

`- (id)initWithDataPath:(NSString *)dataPath language:(NSString *)language`

Initialize a new `Tesseract` instance.

- `dataPath`: a relative path from the application bundle to the `.traineddata` files. You can find these files from [the tesseract downloads section](http://code.google.com/p/tesseract-ocr/downloads/list).
- `language`: language used for recognition. Ex: `eng`. Tesseract will search for a `eng.traineddata` file in the `dataPath` directory.

Returns `nil` if instanciation failed.


### -setVariableValue:forKey: ###

`- (void)setVariableValue:(NSString *)value forKey:(NSString *)key`

Set Tesseract variable `key` to `value`. See <http://www.sk-spell.sk.cx/tesseract-ocr-en-variables> for a complete (but not up-to-date) list.

For instance, use `tessedit_char_whitelist` to restrict characters to a specific set.

### -setImage: ###

`- (void)setImage:(UIImage *)image`

Set the image to recognize.

### -setLanguage: ###

`- (BOOL)setLanguage:(NSString *)language`

Override the language defined with `-initWithDataPath:language:`.

### -recognize ###

`- (BOOL)recognize`

Start text recognition. You might want to launch this process in background with `NSObject`'s `-performSelectorInBackground:withObject:`.

### -recognizedText ###

`- (NSString *)recognizedText`

Get the text extracted from the image.

0 comments on commit c515b25

Please sign in to comment.