This is my first Android App project and I am trying to apply OCR function in my Android App by using Easy OCR library made by Priyank Verma's Easy OCR Library as it is the most simplified & most recent OCR library I can get on. But I think the creator of that library wont answer people's query in his own blog, so I try to ask here. If this is not a good question, I will delete it.
So here's the problem, I have an app with four tabs and in one of the tabs, I tried to use the library example which I try to apply them in my tab. In that tab, there's a 'Scan' button that will take a picture, save it and then scan it. After that, it should return output of text characters from the scanning process. And the execution of the app successfully return with zero error.
But the problem here is, it failed to save the file by which it will lead the failure of the scanning process thus returning nothing. I can't see any problem here, maybe someone with sharp eyes can detect them?
---------- From My App's Tab ----------
My Tab's XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".Tab2"
android:gravity="center_horizontal"
>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:layout_marginTop="45dp"
android:layout_gravity="center_horizontal"
android:textSize="8pt"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
android:layout_marginTop="20dp"
android:text="Scan"
android:layout_gravity="center_vertical" />
</LinearLayout>
My Tab Java
package com.kaydarinapp.queueappv2;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.wordpress.priyankvex.easyocrscannerdemo.Config;
import com.wordpress.priyankvex.easyocrscannerdemo.EasyOcrScanner;
import com.wordpress.priyankvex.easyocrscannerdemo.EasyOcrScannerListener;
/**
* Created by Kaydarin on 6/1/2016.
*/
//Our class extending fragment
public class Tab2 extends Fragment implements EasyOcrScannerListener {
private LinearLayout linearLayout;
private FragmentActivity fragActivity;
EasyOcrScanner mEasyOcrScanner;
TextView textView;
ProgressDialog mProgressDialog;
Button btnCapture;
//Overriden method onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fragActivity = super.getActivity();
linearLayout = (LinearLayout) inflater.inflate(R.layout.tab2, container, false);
textView = (TextView) fragActivity.findViewById(R.id.textView);
// initialize EasyOcrScanner instance.
mEasyOcrScanner = new EasyOcrScanner(getActivity(), "EasyOcrScanner",
Config.REQUEST_CODE_CAPTURE_IMAGE, "eng");
// Set ocrScannerListener
mEasyOcrScanner.setOcrScannerListener(this);
btnCapture = (Button) linearLayout.findViewById(R.id.button);
btnCapture.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
mEasyOcrScanner.takePicture();
}
});
return linearLayout;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Call onImageTaken() in onActivityResult.
if (resultCode == getActivity().RESULT_OK && requestCode == Config.REQUEST_CODE_CAPTURE_IMAGE){
mEasyOcrScanner.onImageTaken();
}
}
/**
* Callback when after taking picture, scanning process starts.
* Good place to show a progress dialog.
* @param filePath file path of the image file being processed.
*/
@Override
public void onOcrScanStarted(String filePath) {
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setMessage("Scanning...");
mProgressDialog.show();
}
/**
* Callback when scanning is finished.
* Good place to hide teh progress dialog.
* @param bitmap Bitmap of image that was scanned.
* @param recognizedText Scanned text.
*/
@Override
public void onOcrScanFinished(Bitmap bitmap, String recognizedText) {
textView.setText(recognizedText);
if (mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
}
}
---------- From Easy OCR Library ----------
Config Java
package com.wordpress.priyankvex.easyocrscannerdemo;
/**
* Created by Priyank(@priyankvex) on 27/8/15.
*/
public class Config {
public static String TAG = "OcrScanner";
public static int REQUEST_CODE_CAPTURE_IMAGE = 1995;
}
EasyOCRScannerListener Java
package com.wordpress.priyankvex.easyocrscannerdemo;
import android.graphics.Bitmap;
/**
* Created by Priyank(@priyankvex) on 27/8/15.
*
* Interface for the callbacks for {@link EasyOcrScanner}.
*/
public interface EasyOcrScannerListener {
public void onOcrScanStarted(String filePath);
public void onOcrScanFinished(Bitmap bitmap, String recognizedText);
}
EasyOCRScanner Java
package com.wordpress.priyankvex.easyocrscannerdemo;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import java.io.File;
import java.util.Calendar;
/**
* Created by Priyank(@priyankvex) on 27/8/15.
*
* Class to handle scanning of image.
*/
public class EasyOcrScanner {
protected Activity mActivity;
private String directoryPathOriginal;
private String filePathOriginal;
private int requestCode;
private EasyOcrScannerListener mOcrScannerListener;
private String trainedDataCode;
public EasyOcrScanner(Activity activity, String directoryPath, int requestCode, String trainedDataCode){
this.mActivity = activity;
this.directoryPathOriginal = directoryPath;
this.requestCode = requestCode;
this.trainedDataCode = trainedDataCode;
}
public void takePicture(){
Intent e = new Intent("android.media.action.IMAGE_CAPTURE");
this.filePathOriginal = FileUtils.getDirectory(this.directoryPathOriginal) + File.separator + Calendar.getInstance().getTimeInMillis() + ".jpg";
e.putExtra("output", Uri.fromFile(new File(this.filePathOriginal)));
startActivity(e);
}
public void onImageTaken(){
Log.d(Config.TAG, "onImageTaken with path " + this.filePathOriginal);
ImageProcessingThread thread = new ImageProcessingThread(this.mOcrScannerListener,
this.filePathOriginal, this.directoryPathOriginal, this.mActivity, this.trainedDataCode);
thread.execute();
}
private void startActivity(Intent intent){
if(this.mActivity != null) {
this.mActivity.startActivityForResult(intent, this.requestCode);
}
}
public void setOcrScannerListener(EasyOcrScannerListener mOcrScannerListener) {
this.mOcrScannerListener = mOcrScannerListener;
}
}
FileUtils Java
package com.wordpress.priyankvex.easyocrscannerdemo;
import android.os.Environment;
import android.util.Log;
import java.io.File;
/**
* Created by Priyank(@priyankvex) on 27/8/15.
*/
public class FileUtils {
public static String getDirectory(String folderName) {
File directory = null;
directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + folderName);
if(!directory.exists()) {
directory.mkdirs();
}
return directory.getAbsolutePath();
}
public static String getTessdataDirectory(String directoryPath){
File tessdataDirectory = new File(directoryPath + "/tessdata");
if (tessdataDirectory.mkdirs()){
Log.d(Config.TAG, "tessdata directory created");
}
return tessdataDirectory.getAbsolutePath();
}
}
ImageProcessingThread Java
package com.wordpress.priyankvex.easyocrscannerdemo;
import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.util.Log;
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;
/**
* Created by Priyank(@priyankvex) on 27/8/15.
*
* Async Task to process the image and scan the image using tesseract library.
* Equipped with proper callbacks.
*/
public class ImageProcessingThread extends AsyncTask<Void, Void, Void> {
private EasyOcrScannerListener mOcrScannerListener;
private String filePath;
private Bitmap mBitmap;
private String scannedText;
// trained data file used by Tesseract will be copied in directoryPath/tessdata
private String directoryPath;
private String absoluteDirectoryPath;
private Activity mActivity;
String trainedDataCode;
public ImageProcessingThread(EasyOcrScannerListener ocrScannerListener, String filePath,
String directoryPath, Activity activity, String trainedDataCode) {
this.mOcrScannerListener = ocrScannerListener;
this.filePath = filePath;
this.directoryPath = directoryPath;
this.absoluteDirectoryPath = FileUtils.getDirectory(this.directoryPath);
this.mActivity = activity;
this.trainedDataCode = trainedDataCode;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mOcrScannerListener.onOcrScanStarted(this.filePath);
}
@Override
protected Void doInBackground(Void... params) {
processImage();
makeTessdataReady();
scannedText = scanImage();
Log.d(Config.TAG, "Scanned test : " + scannedText);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mOcrScannerListener.onOcrScanFinished(mBitmap, scannedText);
}
private void processImage() {
int imageOrientationCode = getImageOrientation();
Bitmap rawBitmap = getBitmapFromPath();
// Getting the bitmap in right orientation.
this.mBitmap = rotateBitmap(rawBitmap, imageOrientationCode);
}
private Bitmap getBitmapFromPath() {
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(this.filePath, bmOptions);
return bitmap;
}
private int getImageOrientation() {
ExifInterface exif = null;
try {
exif = new ExifInterface(this.filePath);
} catch (IOException e) {
e.printStackTrace();
}
assert exif != null;
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
return orientation;
}
private Bitmap rotateBitmap(Bitmap bitmap, int orientation){
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
private String scanImage(){
TessBaseAPI baseApi = new TessBaseAPI();
Log.d(Config.TAG, "Data path : " + FileUtils.getDirectory(this.directoryPath));
baseApi.init(FileUtils.getDirectory(this.directoryPath) + "/", this.trainedDataCode);
baseApi.setImage(this.mBitmap);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
return recognizedText;
}
private void makeTessdataReady(){
// created tessdata directory if necessary under absoluteDirectoryPath and returns its absolute path.
String tessdirectoryPath = FileUtils.getTessdataDirectory(this.absoluteDirectoryPath);
if (!(new File(tessdirectoryPath+ "/" + this.trainedDataCode + ".traineddata")).exists()) {
try {
AssetManager assetManager = mActivity.getAssets();
InputStream in = assetManager.open("tessdata/" + this.trainedDataCode + ".traineddata");
//GZIPInputStream gin = new GZIPInputStream(in);
// Output stream with the location where we have to write the eng.traineddata file.
OutputStream out = new FileOutputStream(tessdirectoryPath + "/" + this.trainedDataCode
+ ".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(Config.TAG, "Copied " + " traineddata");
} catch (IOException e) {
Log.e(Config.TAG, "Was unable to copy " + " traineddata " + e.toString());
}
}
else{
Log.d(Config.TAG, "tessdata already present");
}
}
}
Hope someone can me help here. Really appreciate it.
Aucun commentaire:
Enregistrer un commentaire