Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Always Null returned after cropping a photo from a Uri in Android Lollipop?

I tried to crop an image from a Uri after taking a photo or picking a picture. And my codes are like these:

public static void cropImage(Uri uri, Activity activity, int action_code) {
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(uri, "image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("outputX", 600);
    intent.putExtra("outputY", 600);
    intent.putExtra("scale", true);
    intent.putExtra("return-data", true);
    if (intent.resolveActivity(activity.getPackageManager()) != null) {
        activity.startActivityForResult(intent, action_code);
    } else {
        Toast.makeText(activity, "No Crop App Available", Toast.LENGTH_SHORT).show();
    }
}

And overridding onActivityResult() like this:

if (resultCode == Activity.RESULT_OK && requestCode == Utils.CODE_CROP_IMAGE) {
    Bundle extras = data.getExtras();
    showCenterToast("ccc");
    if (extras != null) {
        showCenterToast("CCC");
        Bitmap photo = extras.getParcelable("data");
        ivAvatar.setImageBitmap(photo); // display image in ImageView
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(Utils.AVATAR_FILE);
            photo.compress(Bitmap.CompressFormat.PNG, 100, fos);// (0-100)compressing file
            showCenterToast("DDD");
            Utils.AVATAR_FILE_TMP.delete();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
           IoUtil.closeSilently(fos);
        }
    }
}

On devices in Android Pre-Lollipop, I was able to obtain Bitmap photo and display it in an ImageView. But, on Android Lollipop, I always got null from data.getExtras();.

I googled a lot but got few useful things about cropping an image on Android Lollipop.

Android changed its returning mechanism of cropping of com.android.camera.action.CROP on Lollipop. So, what is the new mechanism? How could I get the returned Bitmap after cropping on Lollipop?

Any tips will be appreciated. Thanks in advance.

like image 609
SilentKnight Avatar asked Jul 07 '15 07:07

SilentKnight


1 Answers

I think that your problem has nothing to do with Android version but the image you want to be cropped. Cropping image processed in class com.android.gallery3d.filtershow.crop.CropActivity#BitmapIOTask. When the image is too large to return, it will try to return the thumb of the image, and will return null sometimes. To avoid this, you can get the uri of cropped image instead of bitmap by setting intent.putExtra(MediaStore.EXTRA_OUTPUT, tmpUri); where tmpUri is an uri created to hold the result. And then you can get the bitmap from tmpUri.

Sample code:

private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg";//temp file
private static Uri tmpUri = Uri.parse(IMAGE_FILE_LOCATION);//The Uri to store the big bitmap

public static void cropImage(Uri uri, Activity activity, int action_code) {
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(uri, "image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("outputX", 600);
    intent.putExtra("outputY", 600);
    intent.putExtra("scale", true);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, tmpUri);
    if (intent.resolveActivity(activity.getPackageManager()) != null) {
        activity.startActivityForResult(intent, action_code);
    } else {
        Toast.makeText(activity, "No Crop App Available", Toast.LENGTH_SHORT).show();
    }
}

And in function onActivityResult:

if (resultCode == Activity.RESULT_OK && requestCode == Utils.CODE_CROP_IMAGE) {
    // Bundle extras = data.getExtras();
    Uri uri = data.getData();
    showCenterToast("ccc");
    if (uri != null) {
        showCenterToast("CCC");
        // Bitmap photo = null;
        // if (tmpUri != null) {
        //     photo = decodeBitmapFromUri(tmpUri); // Get bitmap from uri.
        // }

        Bitmap photo = decodeUriAsBitmap(uri);
        ivAvatar.setImageBitmap(photo); // display image in ImageView
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(Utils.AVATAR_FILE);
            photo.compress(Bitmap.CompressFormat.PNG, 100, fos);// (0-100)compressing file
            showCenterToast("DDD");
            Utils.AVATAR_FILE_TMP.delete();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
           IoUtil.closeSilently(fos);
        }
    } else {
        showCenterToast("Uri is NULL");
    }
}

private Bitmap decodeUriAsBitmap(Uri uri){
    Bitmap bitmap = null;
    try {
        bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return null;
    }
    return bitmap;
}

I have not test whether my code was correct, but I think you can fix the bugs.

like image 75
GGCoke Avatar answered Oct 14 '22 07:10

GGCoke