Android version with tesseract-android-tools-library - android

I have developed one OCR application which works perfectly on Android version 4.0 but not on 2.2 and 2.3 Android version. I don't know what's the problem with this versions. I searched a lot on Google but no reason found.
package com.datumdroid.android.ocr.simple;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.googlecode.tesseract.android.TessBaseAPI;
public class SimpleAndroidOCRActivity extends Activity {
public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
public static final String DATA_PATH = Environment
.getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
// You should have the trained data file in assets folder
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
public static final String lang = "eng";
private static final String TAG = "SimpleAndroidOCR.java";
protected Button _button;
// protected ImageView _image;
protected EditText _field;
protected String _path;
protected boolean _taken;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v(TAG, "ERROR: Creation of directory " + path + " on
sdcard failed");
return;
} else {
Log.v(TAG, "Created directory " + path + " on sdcard");
}
}
}
// lang.traineddata file with the app (in assets folder)
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
// This area needs work and optimization
if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata/eng.traineddata");
//GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH
+ "tessdata/eng.traineddata");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
//while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
//gin.close();
out.close();
Log.v(TAG, "Copied " + lang + " traineddata");
} catch (IOException e) {
Log.e(TAG, "Was unable to copy " + lang + " traineddata " +
e.toString());
}
}
// _image = (ImageView) findViewById(R.id.image);
_field = (EditText) findViewById(R.id.field);
_button = (Button) findViewById(R.id.button);
_button.setOnClickListener(new ButtonClickHandler());
_path = DATA_PATH + "/ocr.jpg";
}
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
Log.v(TAG, "Starting Camera app");
startCameraActivity();
}
}
// Simple android photo capture:
// http://labs.makemachine.net/2010/03/simple-android-photo-capture/
protected void startCameraActivity() {
File file = new File(_path);
Uri outputFileUri = Uri.fromFile(file);
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "resultCode: " + resultCode);
if (resultCode == -1) {
onPhotoTaken();
} else {
Log.v(TAG, "User cancelled");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN, _taken);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState()");
if (savedInstanceState.getBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN)) {
onPhotoTaken();
}
}
protected void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.v(TAG, "Orient: " + exifOrientation);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
Log.v(TAG, "Rotation: " + rotate);
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
// Convert to ARGB_8888, required by tess
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
} catch (IOException e) {
Log.e(TAG, "Couldn't correct orientation: " + e.toString());
}
// _image.setImageBitmap( bitmap );
Log.v(TAG, "Before baseApi");
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
// You now have the text in recognizedText var, you can do anything with it.
// We will display a stripped out trimmed alpha-numeric version of it (if lang is
eng)
// so that garbage doesn't make it to the display.
Log.v(TAG, "OCRED TEXT: " + recognizedText);
if ( lang.equalsIgnoreCase("eng") ) {
recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
}
recognizedText = recognizedText.trim();
if ( recognizedText.length() != 0 ) {
_field.setText(_field.getText().toString().length() == 0 ? recognizedText :
_field.getText() + " " + recognizedText);
_field.setSelection(_field.getText().toString().length());
}
// Cycle done.
}
// www.Gaut.am was here
// Thanks for reading!
}

Related

How to fix UnsatisfiedLinkError for tesseract in android

i am trying to use "tesseract" for android
i am using following libraries
compile 'org.bytedeco.javacpp-presets:tesseract:3.04.01-1.3'
compile 'org.bytedeco:javacpp:1.3.2'
i have the train data in assets.
my source code if the main activity is following:
package mr.t.mister.mr;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.bytedeco.javacpp.lept.PIX;
import org.bytedeco.javacpp.tesseract.TessBaseAPI;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static org.bytedeco.javacpp.lept.pixRead;
//import com.googlecode.tesseract.android.TessBaseAPI;
public class SimpleAndroidOCRActivity extends Activity {
public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
public static final String DATA_PATH = Environment
.getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
// You should have the trained data file in assets folder
// You can get them at:
// https://github.com/tesseract-ocr/tessdata
public static final String lang = "eng";
private static final String TAG = "SimpleAndroidOCR.java";
protected Button _button;
// protected ImageView _image;
protected EditText _field;
protected String _path;
protected boolean _taken;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
return;
} else {
Log.v(TAG, "Created directory " + path + " on sdcard");
}
}
}
// lang.traineddata file with the app (in assets folder)
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
// This area needs work and optimization
if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata/" + lang + ".traineddata");
//GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH
+ "tessdata/" + lang + ".traineddata");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
//while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
//gin.close();
out.close();
Log.v(TAG, "Copied " + lang + " traineddata");
} catch (IOException e) {
Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
}
}
// _image = (ImageView) findViewById(R.id.image);
_field = (EditText) findViewById(R.id.field);
_button = (Button) findViewById(R.id.button);
_button.setOnClickListener(new ButtonClickHandler());
_path = DATA_PATH + "/ocr.jpg";
}
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
Log.v(TAG, "Starting Camera app");
startCameraActivity();
}
}
// Simple android photo capture:
// http://labs.makemachine.net/2010/03/simple-android-photo-capture/
protected void startCameraActivity() {
File file = new File(_path);
Uri outputFileUri = Uri.fromFile(file);
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "resultCode: " + resultCode);
if (resultCode == -1) {
onPhotoTaken();
} else {
Log.v(TAG, "User cancelled");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN, _taken);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState()");
if (savedInstanceState.getBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN)) {
onPhotoTaken();
}
}
protected void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.v(TAG, "Orient: " + exifOrientation);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
Log.v(TAG, "Rotation: " + rotate);
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
// Convert to ARGB_8888, required by tess
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
} catch (IOException e) {
Log.e(TAG, "Couldn't correct orientation: " + e.toString());
}
// _image.setImageBitmap( bitmap );
Log.v(TAG, "Before baseApi");
TessBaseAPI baseApi = new TessBaseAPI();
//baseApi.setDebug(true);
//baseApi.Init()
baseApi.Init(DATA_PATH, lang);
PIX image = pixRead(_path);
//PIX image = pixRead(args.length > 0 ? args[0] : "/usr/src/tesseract/testing/phototest.tif");
baseApi.SetImage(image);
String recognizedText = baseApi.GetUTF8Text().getString(); //baseApi.getUTF8Text();
baseApi.End();
// You now have the text in recognizedText var, you can do anything with it.
// We will display a stripped out trimmed alpha-numeric version of it (if lang is eng)
// so that garbage doesn't make it to the display.
Log.v(TAG, "OCRED TEXT: " + recognizedText);
if ( lang.equalsIgnoreCase("eng") ) {
recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
}
recognizedText = recognizedText.trim();
if ( recognizedText.length() != 0 ) {
_field.setText(_field.getText().toString().length() == 0 ? recognizedText : _field.getText() + " " + recognizedText);
_field.setSelection(_field.getText().toString().length());
}
// Cycle done.
}
// www.Gaut.am was here
// Thanks for reading!
}
when i try to start tesseract, App crashes. i get following things:
05-09 20:18:09.187 26906-26906/mr.t.mister.mr E/AndroidRuntime: FATAL EXCEPTION: main
Process: mr.t.mister.mr, PID: 26906
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/mr.t.mister.mr-2/base.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_dependencies_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_0_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_1_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_2_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_3_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_4_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_5_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_6_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_7_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_8_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libjnilept.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:963)
at org.bytedeco.javacpp.Loader.load(Loader.java:764)
at org.bytedeco.javacpp.Loader.load(Loader.java:671)
at org.bytedeco.javacpp.lept.<clinit>(lept.java:10)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:309)
at org.bytedeco.javacpp.Loader.load(Loader.java:726)
at org.bytedeco.javacpp.Loader.load(Loader.java:671)
at org.bytedeco.javacpp.tesseract$TessBaseAPI.<clinit>(tesseract.java:3648)
at mr.t.mister.mr.SimpleAndroidOCRActivity.onPhotoTaken(SimpleAndroidOCRActivity.java:214)
at mr.t.mister.mr.SimpleAndroidOCRActivity.onActivityResult(SimpleAndroidOCRActivity.java:138)
at android.app.Activity.dispatchActivityResult(Activity.java:6192)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3570)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617)
at android.app.ActivityThread.access$1300(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/mr.t.mister.mr-2/base.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_dependencies_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_0_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_1_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_2_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_3_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_4_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_5_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_6_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_7_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_8_apk.apk", zip file "/data/app/mr.t.mister.mr-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "liblept.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:963)
at org.bytedeco.javacpp.Loader.load(Loader.java:752)
at org.bytedeco.javacpp.Loader.load(Loader.java:671) 
at org.bytedeco.javacpp.lept.<clinit>(lept.java:10) 
at java.lang.Class.classForName(Native Method) 
at java.lang.Class.forName(Class.java:309) 
at org.bytedeco.javacpp.Loader.load(Loader.java:726) 
at org.bytedeco.javacpp.Loader.load(Loader.java:671) 
at org.bytedeco.javacpp.tesseract$TessBaseAPI.<clinit>(tesseract.java:3648) 
at mr.t.mister.mr.SimpleAndroidOCRActivity.onPhotoTaken(SimpleAndroidOCRActivity.java:214) 
at mr.t.mister.mr.SimpleAndroidOCRActivity.onActivityResult(SimpleAndroidOCRActivity.java:138) 
at android.app.Activity.dispatchActivityResult(Activity.java:6192) 
at android.app.ActivityThread.deliverResults(ActivityThread.java:3570) 
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617) 
at android.app.ActivityThread.access$1300(ActivityThread.java:151) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5254) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
05-09 20:18:09.282 26906-26919/mr.t.mister.mr I/art: Background partial concurrent mark sweep GC freed 798(72KB) AllocSpace objects, 2(91KB) LOS objects, 41% free, 1438KB/2MB, paused 14.815ms total 39.575ms
Unsatisfied link error is produced when Android is not able to obtain a .so library.
Make sure that all your .so are under in their corresponding folder. One or several of the followings -> https://developer.android.com/ndk/guides/abis.html?hl=es
src
---main
------java
---------jnilibs
------------armeabi
------------arm64-v8a
------------...
It is possible you experiment the problem also if your device's processor does not match one of the abi you defined.
You can force your app to use a defined set of abis modifying build.gradle
defaultConfig {
....
ndk.abiFilters 'armeabi', 'arm64-v8a'
}
I was having same issue. When I included all the dependencies as below using *, it vanished.
import org.bytedeco.javacpp.*;
import org.bytedeco.leptonica.*;
import org.bytedeco.tesseract.*;
import static org.bytedeco.leptonica.global.lept.*;
import static org.bytedeco.tesseract.global.tesseract.*;

Android studio is not importing file

I am developing app that is text detection using ocr.
I get the source code from https://github.com/GautamGupta/Simple-Android-OCR. When i am using latest android studio. I didn't get the import file of TessBaseAPI. I try add tess-two to project modules. But it is not working. How it possible to run, the below shows the source where i wrote.
package com.acs.ocr;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class
MainActivity extends AppCompatActivity {
public static final String PACKAGE_NAME = "com.datumdroid.ocr";
public static final String DATA_PATH = Environment
.getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
public static final String lang = "eng";
private static final String TAG = "MainActivity.java";
protected Button _button;
// protected ImageView _image;
protected EditText _field;
protected String _path;
protected boolean _taken;
protected static final String PHOTO_TAKEN = "photo_taken";
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] paths = new String[]{DATA_PATH, DATA_PATH + "tessdata/"};
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
return;
} else {
Log.v(TAG, "Created directory " + path + " on sdcard");
}
}
}
if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata/" + lang + ".traineddata");
//GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH
+ "tessdata/" + lang + ".traineddata");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
//while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
//gin.close();
out.close();
Log.v(TAG, "Copied " + lang + " traineddata");
} catch (IOException e) {
Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
}
}
// _image = (ImageView) findViewById(R.id.image);
_field = (EditText) findViewById(R.id.field);
_button = (Button) findViewById(R.id.button);
_button.setOnClickListener(new ButtonClickHandler());
_path = DATA_PATH + "/ocr.jpg";
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.acs.ocr/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app URL is correct.
Uri.parse("android-app://com.acs.ocr/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
Log.v(TAG, "Starting Camera app");
startCameraActivity();
}
}
protected void startCameraActivity() {
File file = new File(_path);
Uri outputFileUri = Uri.fromFile(file);
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "resultCode: " + resultCode);
if (resultCode == -1) {
onPhotoTaken();
} else {
Log.v(TAG, "User cancelled");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(MainActivity.PHOTO_TAKEN, _taken);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState()");
if (savedInstanceState.getBoolean(MainActivity.PHOTO_TAKEN)) {
onPhotoTaken();
}
}
protected void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.v(TAG, "Orient: " + exifOrientation);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
Log.v(TAG, "Rotation: " + rotate);
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
// Convert to ARGB_8888, required by tess
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
} catch (IOException e) {
Log.e(TAG, "Couldn't correct orientation: " + e.toString());
}
// _image.setImageBitmap( bitmap );
Log.v(TAG, "Before baseApi");
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
// You now have the text in recognizedText var, you can do anything with it.
// We will display a stripped out trimmed alpha-numeric version of it (if lang is eng)
// so that garbage doesn't make it to the display.
Log.v(TAG, "OCRED TEXT: " + recognizedText);
if (lang.equalsIgnoreCase("eng")) {
recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
}
recognizedText = recognizedText.trim();
if (recognizedText.length() != 0) {
_field.setText(_field.getText().toString().length() == 0 ? recognizedText : _field.getText() + " " + recognizedText);
_field.setSelection(_field.getText().toString().length());
}
// Cycle done.
}
}
In this code TessBaseAPI is not importing. How it solve?
Instead of trying to build that project yourself, follow the instructions on the project website to use the pre-built version by adding
compile 'com.rmtheis:tess-two:6.0.4'
to your app's build.gradle file.

Tressact Arabic OCR app gets stuck

I've followed these links: http://gaut.am/making-an-ocr-android-app-using-tesseract/#comment-184181
http://gaut.am/making-an-ocr-android-app-using-tesseract/
to make an OCR app on android studio. The app works perfectly fine when i include eng.traineddata in the src->main->assets folder
However, when i used ara.traineddata to make an OCR app for arabic, the app gets stuck
I used the debug point to check where the problem might be and it seems that the problem is at
baseApi.init(DATA_PATH, lang);
in MainActivity.java
Here is my MainActivity.java
package com.innam.tryingtomaketesseractwork;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.googlecode.tesseract.android.TessBaseAPI;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends Activity {
public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
public static final String DATA_PATH = Environment
.getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
// You should have the trained data file in assets folder
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
public static final String lang = "ara";
private static final String TAG = "SimpleAndroidOCR.java";
protected Button _button;
// protected ImageView _image;
protected EditText _field;
protected String _path;
protected boolean _taken;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
return;
} else {
Log.v(TAG, "Created directory " + path + " on sdcard");
}
}
}
// lang.traineddata file with the app (in assets folder)
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
// This area needs work and optimization
if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata")).exists()) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata/" + lang + ".traineddata");
//GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH
+ "tessdata/" + lang + ".traineddata");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
//while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
//gin.close();
out.close();
Log.v(TAG, "Copied " + lang + " traineddata");
} catch (IOException e) {
Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
}
}
// _image = (ImageView) findViewById(R.id.image);
_field = (EditText) findViewById(R.id.field);
_button = (Button) findViewById(R.id.button);
_button.setOnClickListener(new ButtonClickHandler());
_path = DATA_PATH + "/ocr.jpg";
}
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
Log.v(TAG, "Starting Camera app");
startCameraActivity();
}
}
// Simple android photo capture:
// http://labs.makemachine.net/2010/03/simple-android-photo-capture/
protected void startCameraActivity() {
File file = new File(_path);
Uri outputFileUri = Uri.fromFile(file);
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "resultCode: " + resultCode);
if (resultCode == -1) {
onPhotoTaken();
} else {
Log.v(TAG, "User cancelled");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(MainActivity.PHOTO_TAKEN, _taken);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState()");
if (savedInstanceState.getBoolean(MainActivity.PHOTO_TAKEN)) {
onPhotoTaken();
}
}
protected void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.v(TAG, "Orient: " + exifOrientation);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
Log.v(TAG, "Rotation: " + rotate);
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
// Convert to ARGB_8888, required by tess
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
} catch (IOException e) {
Log.e(TAG, "Couldn't correct orientation: " + e.toString());
}
// _image.setImageBitmap( bitmap );
Log.v(TAG, "Before baseApi");
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
// You now have the text in recognizedText var, you can do anything with it.
// We will display a stripped out trimmed alpha-numeric version of it (if lang is eng)
// so that garbage doesn't make it to the display.
Log.v(TAG, "OCRED TEXT: " + recognizedText);
if ( lang.equalsIgnoreCase("eng") ) {
recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
}
recognizedText = recognizedText.trim();
if ( recognizedText.length() != 0 ) {
_field.setText(_field.getText().toString().length() == 0 ? recognizedText : _field.getText() + " " + recognizedText);
_field.setSelection(_field.getText().toString().length());
}
// Cycle done.
}
// www.Gaut.am was here
// Thanks for reading!
}
logcat:
08-04 12:58:38.900 24836-24836/com.innam.tryingtomaketesseractwork D/libEGL: loaded /system/lib/egl/libEGL_mali.so
08-04 12:58:38.905 24836-24836/com.innam.tryingtomaketesseractwork D/libEGL: loaded /system/lib/egl/libGLESv1_CM_mali.so
08-04 12:58:38.905 24836-24836/com.innam.tryingtomaketesseractwork D/libEGL: loaded /system/lib/egl/libGLESv2_mali.so
[ 08-04 12:58:38.910 24836:24836 D/ ]
Device driver API match
Device driver API version: 10
User space API version: 10
[ 08-04 12:58:38.910 24836:24836 D/ ]
mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Tue Oct 16 15:37:13 KST 2012
08-04 12:58:38.960 24836-24836/com.innam.tryingtomaketesseractwork D/OpenGLRenderer: Enabling debug mode 0
08-04 12:58:38.965 24836-24836/com.innam.tryingtomaketesseractwork E/SensorManager: thread start
08-04 12:58:38.965 24836-24836/com.innam.tryingtomaketesseractwork D/SensorManager: registerListener :: handle = 1 name= LIS3DH Acceleration Sensor delay= 200000
Any help will be highly appreciated
You'd need all the ara.cube.* files also.
https://github.com/tesseract-ocr/tessdata

Tesseract - Help me understand datapath

Can someone explain what exactly is going on and how I can rectify it. So I understand tesseract has to have an image to target and presumably this would be the bitmap I've captured and tried to save. That saved location would be my _path variable. Now what is the DATA_PATH for tesseract? Does the image need to be stored in a folder called 'tesseract' ? Do I create that folder and store some kind of training in it? I'm looking for an explanation rather than a code example.
http://gaut.am/making-an-ocr-android-app-using-tesseract/ - I am trying to follow this tutorial and checking others to try and understand the paths which all of them use.
public class MainActivity extends Activity {
private static ImageView imageView;
protected String _path;
// protected static Bitmap bit;
static File myDir;
protected static Bitmap mImageBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.imageView = (ImageView) this.findViewById(R.id.imageView1);
Button photoButton = (Button) this.findViewById(R.id.button1);
_path = Environment.getExternalStorageDirectory() + "/images/test.bmp";
Toast t = Toast.makeText(getApplicationContext(), "HEELLLLLLOO", 100000);
t.show();
photoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// CALL THE PICTURE
dispatchTakePictureIntent(0);
}
});
}
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(mImageBitmap);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile( _path, options );
imageView.setImageBitmap(bitmap);
//_path = path to the image to be OCRed
ExifInterface exif;
try {
exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}
TessBaseAPI baseApi = new TessBaseAPI();
// DATA_PATH = Path to the storage
// lang for which the language data exists, usually "eng"
baseApi.init(_path, "eng"); //THIS SHOULD BE DATA_PATH ?
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
System.out.println(recognizedText);
baseApi.end();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){
handleSmallCameraPhoto(data);
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, actionCode);
}
protected static void identifyunicode() {
// DATA_PATH = Path to the storage
// lang for which the language data exists, usually "eng"
/*
* TessBaseAPI baseApi = new TessBaseAPI();
* baseApi.init(myDir.toString(), "eng"); // myDir + //
* "/tessdata/eng.traineddata" // must be present baseApi.setImage(bit);
* String recognizedText = baseApi.getUTF8Text(); // Log or otherwise //
* display this // string... baseApi.end();
*/
}
}
DataPath is the path where you copied your tessdata files from Assets.
import java.io.File;
import java.util.ArrayList;
import android.os.Environment;
public class Utils {
public static boolean isSDCardMounted() {
boolean isMounted = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
isMounted = true;
} else if (Environment.MEDIA_BAD_REMOVAL.equals(state)) {
isMounted = false;
} else if (Environment.MEDIA_CHECKING.equals(state)) {
isMounted = false;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
isMounted = false;
} else if (Environment.MEDIA_NOFS.equals(state)) {
isMounted = false;
} else if (Environment.MEDIA_REMOVED.equals(state)) {
isMounted = false;
} else if (Environment.MEDIA_UNMOUNTABLE.equals(state)) {
isMounted = false;
} else if (Environment.MEDIA_UNMOUNTED.equals(state)) {
isMounted = false;
}
return isMounted;
}
public static boolean isDirectoryExists(final String filePath) {
boolean isDirectoryExists = false;
File mFilePath = new File(filePath);
if(mFilePath.exists()) {
isDirectoryExists = true;
} else {
isDirectoryExists = mFilePath.mkdirs();
}
return isDirectoryExists;
}
public static boolean deleteFile(final String filePath) {
boolean isFileExists = false;
File mFilePath = new File(filePath);
if(mFilePath.exists()) {
mFilePath.delete();
isFileExists = true;
}
return isFileExists;
}
public static String getDataPath() {
String returnedPath = "";
final String mDirName = "tesseract";
final String mDataDirName = "tessdata";
if(isSDCardMounted()) {
final String mSDCardPath = Environment.getExternalStorageDirectory() + File.separator + mDirName;
if(isDirectoryExists(mSDCardPath)) {
final String mSDCardDataPath = Environment.getExternalStorageDirectory() + File.separator + mDirName +
File.separator + mDataDirName;
isDirectoryExists(mSDCardDataPath);
return mSDCardPath;
}
}
return returnedPath;
}
}
Activity Class
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.TextView;
import com.googlecode.tesseract.android.TessBaseAPI;
public class AndroidCommonTest extends Activity {
private static final String TAG = AndroidCommonTest.class.getSimpleName();
private TextView txtGotTime = null;
private final int START_CODE = 101;
private String mDirPath = null;
private Uri mOutPutUri = null;
private static final String lang = "eng";
private String mPath = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtGotTime = (TextView) findViewById(R.id.txtGotTime);
mDirPath = Utils.getDataPath();
mPath = mDirPath + File.separator + "test.jpg";
android.util.Log.i(TAG, "mDirPath: " + mDirPath + " mPath: " + mPath);
if (!(new File(mDirPath + File.separator + "tessdata" + File.separator + lang + ".traineddata")).exists()) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata" + File.separator + lang + ".traineddata");
OutputStream out = new FileOutputStream(mDirPath + File.separator
+ "tessdata" + File.separator + lang + ".traineddata");
byte[] buf = new byte[8024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
android.util.Log.e(TAG, "Was unable to copy " + lang + " traineddata " + e.toString());
}
} else {
processImage(mDirPath + File.separator + "six.jpg", 0);
}
}
public void getTime(View view) {
android.util.Log.i(TAG, "mDirPath: " + mDirPath + " mPath: " + mPath);
if(mDirPath != null && mDirPath.length() > 0) {
mOutPutUri = Uri.fromFile(new File(mPath));
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mOutPutUri);
startActivityForResult(intent, START_CODE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == START_CODE) {
if(resultCode == Activity.RESULT_OK) {
int rotation = -1;
long fileSize = new File(mPath).length();
android.util.Log.i(TAG, "fileSize " + fileSize);
//Suppose Device Supports ExifInterface
ExifInterface exif;
try {
exif = new ExifInterface(mPath);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90 :
rotation = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180 :
rotation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270 :
rotation = 270;
break;
case ExifInterface.ORIENTATION_NORMAL:
case ExifInterface.ORIENTATION_UNDEFINED:
rotation = 0;
break;
}
android.util.Log.i(TAG, "Exif:rotation " + rotation);
if (rotation != -1) {
processImage(mPath, rotation);
} else {
//Device Does Not Support ExifInterface
Cursor mediaCursor = getContentResolver().query(mOutPutUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.MediaColumns.SIZE },
null, null, null);
if (mediaCursor != null && mediaCursor.getCount() != 0 ) {
while(mediaCursor.moveToNext()){
long size = mediaCursor.getLong(1);
android.util.Log.i(TAG, "Media:size " + size);
if(size == fileSize){
rotation = mediaCursor.getInt(0);
break;
}
}
android.util.Log.i(TAG, "Media:rotation " + rotation);
processImage(mPath, rotation);
} else {
android.util.Log.i(TAG, "Android Problem");
txtGotTime.setText("Android Problem");
}
}
}
catch (IOException exception) {
exception.printStackTrace();
}
} else if(resultCode == Activity.RESULT_CANCELED) {
android.util.Log.i(TAG, "RESULT_CANCELED");
txtGotTime.setText("RESULT_CANCELED");
}
}
}
private void processImage(final String filePath, final int rotation) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
if (bitmap != null) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(mDirPath, lang);
baseApi.setPageSegMode(100);
baseApi.setPageSegMode(7);
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
android.util.Log.i(TAG, "recognizedText: 1 " + recognizedText);
baseApi.end();
if(lang.equalsIgnoreCase("eng")) {
recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
}
android.util.Log.i(TAG, "recognizedText: 2 " + recognizedText.trim());
txtGotTime.setText(recognizedText.trim());
}
}
private void saveImageAndroid(final Bitmap passedBitmap) {
try {
FileOutputStream mFileOutStream = new FileOutputStream(mDirPath + File.separator + "savedAndroid.jpg");
passedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, mFileOutStream);
mFileOutStream.flush();
mFileOutStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Put tessdata folder in Assets.
Do not forget to give reference path of Tess Library.
Thanks.

Force Close After Run Android Simple OCR Aplication

I've follow this tutorial to learn about ocr in android.
http://gaut.am/making-an-ocr-android-app-using-tesseract/
After successfully run the program on my device, take a photo, it force close. As if it failed to analyze the image.
I already put the trained data on my /asset/testdata/
the trained data is downloaded from :
http://code.google.com/p/tesseract-ocr/downloads/list
My logcat show that I've error on
java.lang.ExceptionInInitializerError
Can you teach me how to fix it?
This is the code:
package com.datumdroid.android.ocr.simple;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.googlecode.tesseract.android.TessBaseAPI;
public class SimpleAndroidOCRActivity extends Activity {
public static final String PACKAGE_NAME = "com.datumdroid.android.ocr.simple";
public static final String DATA_PATH = Environment
.getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
// You should have the trained data file in assets folder
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
public static final String lang = "eng";
private static final String TAG = "SimpleAndroidOCR.java";
protected Button _button;
// protected ImageView _image;
protected EditText _field;
protected String _path;
protected boolean _taken;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
public void onCreate(Bundle savedInstanceState) {
String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v(TAG, "ERROR: Creation of directory " + path
+ " on sdcard failed");
return;
} else {
Log.v(TAG, "Created directory " + path + " on sdcard");
}
}
}
// lang.traineddata file with the app (in assets folder)
// You can get them at:
// http://code.google.com/p/tesseract-ocr/downloads/list
// This area needs work and optimization
if (!(new File(DATA_PATH + "tessdata/" + lang + ".traineddata"))
.exists()) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata/eng.traineddata");
// GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH
+ "tessdata/eng.traineddata");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
// while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
// gin.close();
out.close();
Log.v(TAG, "Copied " + lang + " traineddata");
} catch (IOException e) {
Log.e(TAG,
"Was unable to copy " + lang + " traineddata "
+ e.toString());
}
}
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// _image = (ImageView) findViewById(R.id.image);
_field = (EditText) findViewById(R.id.field);
_button = (Button) findViewById(R.id.button);
_button.setOnClickListener(new ButtonClickHandler());
_path = DATA_PATH + "/ocr.jpg";
}
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
Log.v(TAG, "Starting Camera app");
startCameraActivity();
}
}
// Simple android photo capture:
// http://labs.makemachine.net/2010/03/simple-android-photo-capture/
protected void startCameraActivity() {
File file = new File(_path);
Uri outputFileUri = Uri.fromFile(file);
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "resultCode: " + resultCode);
if (resultCode == -1) {
onPhotoTaken();
} else {
Log.v(TAG, "User cancelled");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN, _taken);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState()");
if (savedInstanceState.getBoolean(SimpleAndroidOCRActivity.PHOTO_TAKEN)) {
onPhotoTaken();
}
}
protected void onPhotoTaken() {
_taken = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(_path, options);
try {
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.v(TAG, "Orient: " + exifOrientation);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
Log.v(TAG, "Rotation: " + rotate);
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
// Convert to ARGB_8888, required by tess
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
System.out.println("Bitmap Selesai");
} catch (IOException e) {
Log.e(TAG, "Couldn't correct orientation: " + e.toString());
}
// _image.setImageBitmap( bitmap );
//System.loadLibrary("tess");
System.out.println("Masuk");
Log.v(TAG, "Before baseApi");
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
System.out.println("Keluar");
// You now have the text in recognizedText var, you can do anything with
// it.
// We will display a stripped out trimmed alpha-numeric version of it
// (if lang is eng)
// so that garbage doesn't make it to the display.
Log.v(TAG, "OCRED TEXT: " + recognizedText);
if (lang.equalsIgnoreCase("eng")) {
recognizedText = recognizedText.replaceAll("[^a-zA-Z0-9]+", " ");
}
recognizedText = recognizedText.trim();
if (recognizedText.length() != 0) {
_field.setText(_field.getText().toString().length() == 0 ? recognizedText
: _field.getText() + " " + recognizedText);
_field.setSelection(_field.getText().toString().length());
}
// Cycle done.
}
// www.Gaut.am was here
// Thanks for reading!
}
Do you have this in your AndroidManifest.xml?:
<uses-permission android:name="WRITE_EXTERNAL_STORAGE" />
I notice that you're trying to create files/directories during initialization, maybe this will help
Can you try to add System.loadLibrary("tess"); before initializing tesseract-ocr?

Categories

Resources