我有这个mainActivity java文件,我想显示回OCR的结果。
错误:创建目录/存储/模拟/ 0 / TesseractSample / tessdata失败,检查Android Manifest是否有权写入外部存储。
无法将文件复制到tessdata java.io.FileNotFoundException:/storage/emulated/0/TesseractSample/tessdata/eng.traineddata:open failed:ENOENT(没有这样的文件或目录)
3.无法解码流:java.io.FileNotFoundException:/storage/emulated/0/TesseractSample/imgs/ocr.jpg:open failed:EACCES(Permission denied)
数据路径必须包含子文件夹tessdata!
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
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 {
private static final String TAG = MainActivity.class.getSimpleName();
static final int PHOTO_REQUEST_CODE = 1;
private TessBaseAPI tessBaseApi;
TextView textView;
Uri outputFileUri;
private static final String lang = "eng";
String result = "empty";
private static final String DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/";
private static final String TESSDATA = "tessdata";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button captureImg = (Button) findViewById(R.id.action_btn);
if (captureImg != null) {
captureImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCameraActivity();
}
});
}
textView = (TextView) findViewById(R.id.textResult);
}
/**
* to get high resolution image from camera
*/
private void startCameraActivity() {
try {
String IMGS_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/imgs";
prepareDirectory(IMGS_PATH);
String img_path = IMGS_PATH + "/ocr.jpg";
outputFileUri = Uri.fromFile(new File(img_path));
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, PHOTO_REQUEST_CODE);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
//making photo
if (requestCode == PHOTO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
prepareTesseract();
startOCR(outputFileUri);
} else {
Toast.makeText(this, "ERROR: Image was not obtained.", Toast.LENGTH_SHORT).show();
}
}
/**
* Prepare directory on external storage
*
* @param path
* @throws Exception
*/
private void prepareDirectory(String path) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.e(TAG, "ERROR: Creation of directory " + path + " failed, check does Android Manifest have permission to write to external storage.");
}
} else {
Log.i(TAG, "Created directory " + path);
}
}
private void prepareTesseract() {
try {
prepareDirectory(DATA_PATH + TESSDATA);
} catch (Exception e) {
e.printStackTrace();
}
copyTessDataFiles(TESSDATA);
}
/**
* Copy tessdata files (located on assets/tessdata) to destination directory
*
* @param path - name of directory with .traineddata files
*/
private void copyTessDataFiles(String path) {
try {
String fileList[] = getAssets().list(path);
for (String fileName : fileList) {
// open file within the assets folder
// if it is not already there copy it to the sdcard
String pathToDataFile = DATA_PATH + path + "/" + fileName;
if (!(new File(pathToDataFile)).exists()) {
InputStream in = getAssets().open(path + "/" + fileName);
OutputStream out = new FileOutputStream(pathToDataFile);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Log.d(TAG, "Copied " + fileName + "to tessdata");
}
}
} catch (IOException e) {
Log.e(TAG, "Unable to copy files to tessdata " + e.toString());
}
}
/**
* don't run this code in main thread - it stops UI thread. Create AsyncTask instead.
* https://developer.android.com/reference/android/os/AsyncTask.html
*
* @param imgUri
*/
private void startOCR(Uri imgUri) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; // 1 - means max size. 4 - means maxsize/4 size. Don't use value <4, because you need more memory in the heap to store your data.
Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);
result = extractText(bitmap);
textView.setText(result);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private String extractText(Bitmap bitmap) {
try {
tessBaseApi = new TessBaseAPI();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
if (tessBaseApi == null) {
Log.e(TAG, "TessBaseAPI is null. TessFactory not returning tess object.");
}
}
tessBaseApi.init(DATA_PATH, lang);
// //EXTRA SETTINGS
// //For example if we only want to detect numbers
// tessBaseApi.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "1234567890");
//
// //blackList Example
// tessBaseApi.setVariable(TessBaseAPI.VAR_CHAR_BLACKLIST, "!@#$%^&*()_+=-qwertyuiop[]}{POIU" +
// "YTRWQasdASDfghFGHjklJKLl;L:'\"\\|~`xcvXCVbnmBNM,./<>?");
Log.d(TAG, "Training file loaded");
tessBaseApi.setImage(bitmap);
String extractedText = "empty result";
try {
extractedText = tessBaseApi.getUTF8Text();
} catch (Exception e) {
Log.e(TAG, "Error in recognizing text.");
}
tessBaseApi.end();
return extractedText;
}
}
答案 0 :(得分:0)
如果您的目标是Android SDK 23或更高版本,除了在Android清单文件中请求权限外,您还必须request permissions from the user at run time。
或者,您可以通过更改build.gradle中的targetSdkVersion
值来定位SDK 22或更低版本。