如何用裁剪的uri覆盖照片的uri?

时间:2016-06-24 14:27:32

标签: 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 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

0 个答案:

没有答案