Search code examples
androidbitmappicasso

Handling Bitmap size before uploading


I let my users upload images from their android Gallery to a back-end for storage.

The issue is if they choose an enormous image which would certainly produce OutOfMemory fault. All I would like to do with the Bitmap, is to make sure it won't produce any OOM error. So only check if it's too large, if so, reduce it's size but keep the aspect ratio, I don't want to crop away parts of the photo. When I download the image back from the backend it'll go through picasso and crop it with .centerCrop() and .fit() into an imageview.

First, here's the activity receiving data from gallery:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode,resultCode,data);
    if(resultCode == RESULT_OK){
        if(requestCode == SELECT_PICTURE){

            Uri selectedImage = data.getData();

            if(!image1_exists){
                attachImage(image1,selectedImage);
            }

        }

    }
}

next, I take the choosen image and display it in the "gallery" layout:

public void attachImage(ImageView image, Uri uri){

    Picasso.with(this).load(uri).resize(500,500).into(mTarget);

    Picasso.with(this).load(uri).centerCrop().fit().into(image);

}

So one Picasso instance is displaying their choosen image and the other should resize the uri data incase it's too large (this is the part I need to change completely), into the Target:

final Target mTarget = new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {

        image_scaled = Bitmap.createScaledBitmap(bitmap, 500,500 * bitmap.getHeight() / bitmap.getWidth(), false);
        if(!image1_exists){
            uploadImage(image_scaled,"image1");
        }

    }
    @Override
    public void onBitmapFailed(Drawable drawable) {
        Log.d("DEBUG", "onBitmapFailed");
    }

    @Override
    public void onPrepareLoad(Drawable drawable) {
        Log.d("DEBUG", "onPrepareLoad");
    }
};

In here I would also like to (as you can see) scale the bitmap to reduce size and save storage space in my back end. But keeping the aspect ratio, without cropping away any part of the image. This might be unnecessary I would imagine, since I will have to do something similar to the large images anyways? If you need to know how the layout of these images look, imagine a profile on Instagram, where all images fit into a square imageview.

Hope someone can make some sense out of this and understand what I'm trying to achieve. Thanks in advance!


Solution

  • I've done this using this bitmap decoding option. Decoding a bitmap using this, will downsample it, resulting in less memory being occupied on the device. Unfortunately, you can only apply it when decoding a bitmap, so it means it won't work with the Picasso target, but I'm sure you can manage without it.