Java 如何覆盖照片';s uri带有裁剪的uri?

Java 如何覆盖照片';s uri带有裁剪的uri?,java,android,ocr,Java,Android,Ocr,我在startOCR函数中不断遇到此错误: 空对象引用上的java.lang.String android.net.Uri.getPath() 我正在尝试拍摄一张照片,然后在将其发送到执行OCR功能之前对其进行裁剪。有人能帮我吗 import android.app.Activity; import android.content.ActivityNotFoundException; import android.support.v7.app.AppCompatActivity; import

我在startOCR函数中不断遇到此错误:

空对象引用上的java.lang.String android.net.Uri.getPath()

我正在尝试拍摄一张照片,然后在将其发送到执行OCR功能之前对其进行裁剪。有人能帮我吗

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
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 java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.googlecode.tesseract.android.TessBaseAPI;

public class Main3Activity extends AppCompatActivity {

    //Log variable.
    private static final String TAG = Main3Activity.class.getSimpleName();

    //Request code is 1
    static final int PHOTO_REQUEST_CODE = 1;

    //Constructing an instance  to the Tesseract API
    private TessBaseAPI tessBaseApi;

    //Getting a reference to the TextView in the XML layout
    TextView textView;
    //Creating a Uri variable that will be holding the point of content to the image.
    Uri outputFileUri;
    final int PIC_CROP = 2;


    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_main3);

        textView = (TextView) findViewById(R.id.OcrResultTextView);

        //Getting reference to the button and setting the onClickListener for the button.
        Button captureImg = (Button) findViewById(R.id.CaptureImageButton);
        if (captureImg != null) {
            captureImg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startCameraActivity();
                }
            });
        }

    }//end of onCreate


    /*************************************************************************************************************************
    Method that will start the camera of the phone.

     ************************************************************************************************************************/
    private void startCameraActivity() {
        try {
            //String variable that will hold the directory of the folder which is to be created within the internal
            //storage of the phone.
            String IMGS_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/imgs";
            prepareDirectory(IMGS_PATH);

            String img_path = IMGS_PATH + "/ocr.jpg";

            //Uri variable (Uniform Resource Identifier) will contain the reference the uri created from a file.
            outputFileUri = Uri.fromFile(new File(img_path));


            //Creating an intent of type action_image_capture which is the standard action that
            //can be sent to have the camera application capture an image and return it.
            final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            //Inserting into the intent extra_output because this is used to indicate a content
            //resolver Uri to be used to store the requested image, can also be used for videos.
            //Also passing in the output Uri which will hold the path to the output image.
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

            //Ensuring that there is a camera activity to handle the intent and if there is,
            //passing in the takePictureIntent and along with the photo request code.
            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                startActivityForResult(takePictureIntent, PHOTO_REQUEST_CODE);
                //At this current point the camera has been initated.
                Log.e(TAG,"Started the camera.");

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

    /*********************************************************************************************************************
        This method will get called after the image is either finished taken or the user decided to cancel the camera.

     ********************************************************************************************************************/
    @Override
    public void onActivityResult(int requestCode, int resultCode,
                                 Intent data) {

        Log.e(TAG, "Photo has been taken.");
        //Method of cropping has to go here
        //CropFunction();


        //Creating photo
        if (requestCode == PHOTO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        Log.e(TAG,"Taken to the confirmation.");
            prepareTesseract();
            //Put the crop here.
            Log.e(TAG, "Starting crop function");
            CropFunction();

            //if(requestCode == PIC_CROP){
              //  Log.e(TAG, "Inside if statement for PIC_CROP");
                //Getting  the returned data and entering it into the Bundle.
                //Bundle extras = data.getExtras();
                //Get the cropped bitmap
  //              Bitmap thePic = extras.getParcelable("data");
                Log.e(TAG, "Calling the startOCR function");
                startOCR(outputFileUri);

//            }
         //   startOCR(outputFileUri);

        } else {
            Toast.makeText(this, "ERROR: Image was not obtained.", Toast.LENGTH_SHORT).show();
        }
    }

    /***************************************************************************************************
    Method to create the directory within the internal storage of the phone.

    Method will first check if the directory has not been created before, if it has not
    it will create the directory and the Log will display the message it has been created.

    If the internal photo directory has already been created this method will just be passed.
     *************************************************************************************************/
    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);
        }
    }

    /************************************************************************
        Method responsible for preparing Tesseract operations.
     ***********************************************************************/
    private void prepareTesseract() {
        try {
            prepareDirectory(DATA_PATH + TESSDATA);
        } catch (Exception e) {
            e.printStackTrace();
        }

        copyTessDataFiles(TESSDATA);
    }

    /*************************************************************************************************

     ****************************************************************************************************/
    private void copyTessDataFiles(String path) {
        try {
            String fileList[] = getAssets().list(path);

            for (String fileName : fileList) {

                //Opening the file within the assets folder
                // In the situation that the fole is no there it will copy it to the sd card
                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());
        }
    }

     /************************************************************************************************
     This function performs the OCR technology within the image provided.
    Function that beings the Optical Character Recognition of the image.
    Function expects to recieve the Uri of a captured image.
     *************************************************************************************************/

    private void startOCR(Uri imgUri) {
        try {
            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;
            Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);

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

            //Setting the string result to the content of the TextView.
            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);

        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;
    }

    private void CropFunction(){

        try{
            Log.e(TAG, "Inside the crop function.");
            Intent cropIntent =  new Intent("com.android.camera.action.CROP");
           // cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            //cropIntent.putExtra("crop", "true");
            //cropIntent.putExtra("return-data", true);
            //startActivityForResult(cropIntent,1);


            //Inserting the imageType and the Uri into the intent.
            cropIntent.setDataAndType(outputFileUri, "image/*");

            //Passing in the  crop properties to the intent.
            cropIntent.putExtra("crop", "true");

            //Indicating and passing in the aspect of the desired crop.
            cropIntent.putExtra("aspectX", 0);
            cropIntent.putExtra("aspectY", 0);

            //Indicating and passing in the output for X and Y.
            cropIntent.putExtra("outputX", 200);
            cropIntent.putExtra("outputY", 150);

            //retrieve data on return
            //changed from true which gives me a bitmap to false which gives me the exact image.
            cropIntent.putExtra("return-data", false);

            cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

            Log.e(TAG,"At the end of the crop function.");
             startActivityForResult(cropIntent, PIC_CROP);

        }catch(ActivityNotFoundException e){
            String errorMessage = "Sorry, your device does not support the crop feature";
            Toast toaster = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
            toaster.show();
        }
    }

}// End of class
导入android.app.Activity;
导入android.content.ActivityNotFoundException;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入android.content.Intent;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.net.Uri;
导入android.os.Environment;
导入android.provider.MediaStore;
导入android.util.Log;
导入android.view.view;
导入android.widget.Button;
导入android.widget.TextView;
导入android.widget.Toast;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入com.googlecode.tesseract.android.TessBaseAPI;
公共类Main3活动扩展了AppCompative活动{
//日志变量。
私有静态最终字符串标记=Main3Activity.class.getSimpleName();
//请求代码是1
静态最终内部照片请求代码=1;
//构造Tesseract API的实例
私有TessBaseAPI TessBaseAPI;
//在XML布局中获取对TextView的引用
文本视图文本视图;
//创建一个Uri变量,该变量将保存图像的内容点。
urioutputfileuri;
最终int PIC_裁剪=2;
私有静态最终字符串lang=“eng”;
String result=“empty”;
私有静态最终字符串数据_PATH=Environment.getExternalStorageDirectory().toString()+“/TesseractSample/”;
私有静态最终字符串TESSDATA=“TESSDATA”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
textView=(textView)findViewById(R.id.OcrResultTextView);
//获取对按钮的引用并为按钮设置onClickListener。
按钮captureImg=(按钮)findViewById(R.id.CaptureImageButton);
if(captureImg!=null){
setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
startCameraActivity();
}
});
}
}//onCreate结束
/*************************************************************************************************************************
方法启动手机摄像头。
************************************************************************************************************************/
私有void startCameraActivity(){
试一试{
//字符串变量,该变量将保存要在内部文件夹中创建的文件夹的目录
//储存手机。
字符串IMGS_PATH=Environment.getExternalStorageDirectory().toString()+“/TesseractSample/IMGS”;
准备目录(IMGS_路径);
字符串img_path=IMGS_path+“/ocr.jpg”;
//Uri变量(统一资源标识符)将包含从文件创建的Uri的引用。
outputFileUri=Uri.fromFile(新文件(img_路径));
//创建类型为action\u image\u capture的意图,这是
//可以发送以让相机应用程序捕获图像并返回。
最终意图takePictureContent=新意图(MediaStore.ACTION\u IMAGE\u CAPTURE);
//插入到intent extra_输出中,因为这用于指示内容
//用于存储请求图像的解析器Uri,也可用于视频。
//还传递输出Uri,该Uri将保存到输出图像的路径。
takePictureContent.putExtra(MediaStore.EXTRA_输出,outputFileUri);
//确保有摄像头活动来处理意图,如果有,
//传递TakePictureContent和照片请求代码。
if(takePictureContent.resolveActivity(getPackageManager())!=null){
startActivityForResult(拍摄图片内容、照片请求代码);
//此时相机已启动。
Log.e(标签“启动照相机”);
}
}捕获(例外e){
Log.e(标记,e.getMessage());
}
}
/*********************************************************************************************************************
此方法将在图像拍摄完成或用户决定取消相机后调用。
********************************************************************************************************************/
@凌驾
在ActivityResult(int请求代码、int结果代码、,
意图(数据){
Log.e(标签“已拍摄照片”);
//种植方法必须在这里
//CropFunction();
//创建照片
if(requestCode==PHOTO\u REQUEST\u CODE&&resultCode==Activity.RESULT\u OK){
Log.e(标签“带到确认处”);
preparetesetract();
//把庄稼放在这儿。
Log.e(标签“开始作物功能”);
CropFunction();
//if(requestCode==PIC_-CROP){
//Log.e(标签“PIC_CROP的内部if语句”);
//获取返回的数据并将其输入到Bundle中。
//Bundle extras=data.getExtras();
//获取裁剪后的位图
//位图thePic=extras.getParcelable(“数据”);
Log.e(标记“调用startOCR函数”);
startOCR(outputFileUri);
//            }
//startOCR(outputFileUri);
}否则{