无法显示OCR的结果

时间:2016-06-22 17:59:25

标签: java android ocr

我有这个mainActivity java文件,我想显示回OCR的结果。

  1. 错误:创建目录/存储/模拟/ 0 / TesseractSample / tessdata失败,检查Android Manifest是否有权写入外部存储。

  2. 无法将文件复制到tessdata java.io.FileNotFoundException:/storage/emulated/0/TesseractSample/tessdata/eng.traineddata:open failed:ENOENT(没有这样的文件或目录)

  3. 3.无法解码流:java.io.FileNotFoundException:/storage/emulated/0/TesseractSample/imgs/ocr.jpg:open failed:EACCES(Permission denied)

    1. 数据路径必须包含子文件夹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;
          }
      }
      

1 个答案:

答案 0 :(得分:0)

如果您的目标是Android SDK 23或更高版本,除了在Android清单文件中请求权限外,您还必须request permissions from the user at run time

或者,您可以通过更改build.gradle中的targetSdkVersion值来定位SDK 22或更低版本。