Search code examples
androidandroid-cameraandroid-gallery

Cropping image won't succeed


I'm trying to take a picture with the camera and after that crop it to then displaying it into an ImageView.

Unfortunatly the startActivityForResult in the crop method you will see in the code below will always return an error result code.

I think I found the baddie that is responsible for that but I don't know how to get it fixed.

First here is the code:

Capture image:

/**
 * Starts Intent to open camera and take picture
 */
private void captureImage() {
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (cameraIntent.resolveActivity(getPackageManager()) != null) {

        File photoFile = null;

        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Toast.makeText(this, "Whoops - could not access external storage!", Toast.LENGTH_SHORT).show();
        }
        if (photoFile != null) {
            Uri photoUri = FileProvider.getUriForFile(this, FILEPROVIDER_AUTHORITY, photoFile);
            contact.setImage(Uri.fromFile(photoFile));
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            try {
                startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(this, "Whoops - something went wrong!", Toast.LENGTH_SHORT).show();
            }
        }
    } else {
        Toast.makeText(this, "Whoops - your device doesn't support capturing images!", Toast.LENGTH_SHORT).show();
    }
}

Crop Image:

/**
 * Starts (unofficial) Intent to crop chosen image which is likely to fail
 */
private void cropImage() {

    Uri photoUri = FileProvider.getUriForFile(this, FILEPROVIDER_AUTHORITY,new File(contact.getImage().getPath()));
    grantUriPermission("com.android.camera", photoUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

    Intent cropIntent = new Intent("com.android.camera.action.CROP");
    cropIntent.setDataAndType(photoUri, "image/*");

    cropIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    cropIntent.putExtra("crop", "true");
    cropIntent.putExtra("aspectX", 1);
    cropIntent.putExtra("aspectY", 1);
    cropIntent.putExtra("outputX", 500);
    cropIntent.putExtra("outputY", 500);
    cropIntent.putExtra("outputFormat", "JPEG");
    cropIntent.putExtra("noFaceDetection", true);
    cropIntent.putExtra("return-data", true);
    cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
    try {
        startActivityForResult(cropIntent, REQUEST_IMAGE_CROP);
    } catch (ActivityNotFoundException e) {
        Toast.makeText(this, "Whoops - your device doesn't support the crop action!", Toast.LENGTH_SHORT).show();
    }
}

onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == RESULT_OK) {

        switch (requestCode) {
            case REQUEST_IMAGE_CAPTURE:
                cropImage();
                break;
            case REQUEST_IMAGE_CHOOSE:
                break;
            case REQUEST_IMAGE_CROP:
                Bitmap tmp = data.getExtras().getParcelable("data");
                previewImageView.setImageBitmap(tmp);
                break;
            default:
                super.onActivityResult(requestCode, resultCode, data);
        }
    } else {
        Toast.makeText(this, "Whoops - something went wrong!", Toast.LENGTH_SHORT).show();
    }
}

Now the baddie who I think is responsible is the com.android.gallery3d app cause everytime the crop intent is fired it throws this exception:

com.android.gallery3d W/CropActivity: cannot open region decoder for file: content://de.hska.mycontacts.fileprovider/contact_images/CONTACT_20180413_155111_.jpg
java.io.IOException: Image format not supported
    at android.graphics.BitmapRegionDecoder.nativeNewInstance(Native Method)
    at android.graphics.BitmapRegionDecoder.newInstance(BitmapRegionDecoder.java:124)
    at com.android.gallery3d.filtershow.crop.CropActivity$BitmapIOTask.doInBackground(CropActivity.java:483)
    at com.android.gallery3d.filtershow.crop.CropActivity$BitmapIOTask.doInBackground(CropActivity.java:421)
    at android.os.AsyncTask$2.call(AsyncTask.java:305)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761) 

com.android.gallery3d W/CropActivity: cannot decode file: content://de.hska.mycontacts.fileprovider/contact_images/CONTACT_20180413_155111_.jpg

I hope somebody can help me with that :)


Solution

  • As CommonsWare already stated in the comments the Intent com.android.camera.action.CROP is not official and won't work on the most devices. Therefore it's a better practice to use a library.

    I ended up using uCrop that is really easy to use and also supports a lot of customization.