1

我正在尝试将谷歌文档转换为位图,以便可以在其中执行 OCR。然而,我得到了错误:

E/BitmapFactory:无法解码流:java.io.FileNotFoundException:/document/acc=4;doc=14882:打开失败:ENOENT(没有这样的文件或目录)

E/ReadFile:位图必须为非空

E/CropTest: 读取位图失败

代码:

/**
 * Fires an intent to spin up the "file chooser" UI and select an image.
 */
public void performFileSearch(View view) {

  // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
  // browser.
  Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

  // Filter to only show results that can be "opened", such as a
  // file (as opposed to a list of contacts or timezones)
  intent.addCategory(Intent.CATEGORY_OPENABLE);

  // Filter to show only images, using the image MIME data type.
  // If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
  // To search for all documents available via installed storage providers,
  // it would be "*/*".
  intent.setType("application/vnd.google-apps.document");

  startActivityForResult(intent, READ_REQUEST_CODE);
}

@Override
public  void onActivityResult(int requestCode, int resultCode, Intent resultData){

  if(requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK){
    Uri uri = null;
    if(resultData != null){
      uri = resultData.getData();
      Log.i(TAG, "Uri" + uri.toString());

      Toast.makeText(MainActivity.this, "Uri:" + uri.toString(), Toast.LENGTH_LONG).show();
      IMGS_PATH = Environment.getExternalStorageDirectory().toString()+ "/TesseractSample/imgs";
      prepareDirectory(IMGS_PATH);
      prepareTesseract();
      startOCR(uri);
    }
  }
}

//Function that begins the OCR functionality.
private void startOCR(Uri imgUri) {
  try {

    Log.e(TAG, "Inside the startOCR function");
    BitmapFactory.Options options = new BitmapFactory.Options();
    // 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.
    options.inSampleSize = 4;
    //  FileOutputStream outStream = new FileOutputStream(String.valueOf(imgUri));
    Bitmap bm = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);
    // bm.compress(Bitmap.CompressFormat.PNG,100,outStream);

    Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath());
    // bitmap = toGrayscale(bitmap);

    //The result variable will hold whatever is returned from "extractText" function.
    result = extractText(bm);

    //Creating the intent to go to the CropTest
    Intent intentToCropTest = new Intent(MainActivity.this, CropTest.class);
    intentToCropTest.putExtra("result",result);
    startActivity(intentToCropTest);

    //Setting the string result to the content of the TextView.
    // textView.setText(result);

  } catch (Exception e) {
    Log.e(TAG, e.getMessage());
  }
}
4

1 回答 1

2

您正试图将 AndroidUri视为文件路径。不要那样做。而是检索 ContentResolver 实例并使用它将 Uri 转换为流:

AssetFileDescriptor fd = context.getContentResolver()
    .openAssetFileDescriptor(uri, "r");
InputStream is = fd.createInputStream();

如果不支持 AssetFileDescriptor(您得到 null 或发生异常),请尝试更直接的路线:

InputStream is = context.getContentResolver().openInputStream();

还有另一种超级强大的内容类型感知方法,它存在了很长时间,但在 Android N 发布时被 Google 自己的开发人员重新发现。它在 ContentProvider 方面需要更多的基础设施(旧版本的 Google 服务可能不支持):

ContentResolver r = getContentResolver();

String[] streamTypes = r.getStreamTypes(uri, "*/*");

AssetFileDescriptor descriptor = r.openTypedAssetFileDescriptor(
                    uri,
                    streamTypes[0],
                    null);

InputStream is = descriptor.createInputStream();

然后使用获得的流创建位图:

Bitmap bitmap = BitmapFactory.decodeStream(is);
于 2016-07-11T18:28:24.887 回答