After a few days struggling to avoid all OutOfMemory errors that I was getting with different devices, I create this:
private Bitmap getDownsampledBitmap(Context ctx, Uri uri, int targetWidth, int targetHeight) { Bitmap bitmap = null; try { BitmapFactory.Options outDimens = getBitmapDimensions(uri); int sampleSize = calculateSampleSize(outDimens.outWidth, outDimens.outHeight, targetWidth, targetHeight); bitmap = downsampleBitmap(uri, sampleSize); } catch (Exception e) { //handle the exception(s) } return bitmap; } private BitmapFactory.Options getBitmapDimensions(Uri uri) throws FileNotFoundException, IOException { BitmapFactory.Options outDimens = new BitmapFactory.Options(); outDimens.inJustDecodeBounds = true; // the decoder will return null (no bitmap) InputStream is= getContentResolver().openInputStream(uri); // if Options requested only the size will be returned BitmapFactory.decodeStream(is, null, outDimens); is.close(); return outDimens; } private int calculateSampleSize(int width, int height, int targetWidth, int targetHeight) { int inSampleSize = 1; if (height > targetHeight || width > targetWidth) { // Calculate ratios of height and width to requested height and // width final int heightRatio = Math.round((float) height / (float) targetHeight); final int widthRatio = Math.round((float) width / (float) targetWidth); // Choose the smallest ratio as inSampleSize value, this will // guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } private Bitmap downsampleBitmap(Uri uri, int sampleSize) throws FileNotFoundException, IOException { Bitmap resizedBitmap; BitmapFactory.Options outBitmap = new BitmapFactory.Options(); outBitmap.inJustDecodeBounds = false; // the decoder will return a bitmap outBitmap.inSampleSize = sampleSize; InputStream is = getContentResolver().openInputStream(uri); resizedBitmap = BitmapFactory.decodeStream(is, null, outBitmap); is.close(); return resizedBitmap; }
This method works with all devices I tested, but I think the quality can be better using other process that I'm not aware.
I hope my code can help other developers in the same situation. I also appreciate if a senior developer can help, giving a suggestion about other process to avoid lose (less) quality in the process.