java.lang.OutofMemoryError: bitmap size exceeds VM budget. This is most common error for us when we are
decoding Bitmap more than 4 MB. In generally before decoding bitmap we do not
know how much bigger the size of a bitmap will be. So its very difficult
problem for us to handle this error in proactive approach But good thing is that
android provide a way to handle this problem.Before decoding bitmap we just
decode it with options.inJustDecodeBounds = true. options is the instance of BitmapFactory.
It does not load bitmap into memory but it help us to find the width and height
of a bitmap so that we can reduce the height and width according to our device
As Bitmaps take
up a lot of memory, especially for rich images like photographs. For example,
the camera on the Galaxy Nexus takes photos up to 2592x1936 pixels (5
megapixels). If the bitmap configuration used is ARGB_8888 (the default from
the Android 2.3 onward) then loading this image into memory takes about 19MB of
memory (2592*1936*4 bytes), immediately exhausting the per-app limit on some
devices.
So we will find actual
height and width of a bitmap as follows...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType; Now scale down the bitmap and load into memory.I use decodeResource() method here but you can use any method(decodeFile etc).So now using following function scale down bitmap public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { if (width > height) { inSampleSize = Math.round((float)height / (float)reqHeight); } else { inSampleSize = Math.round((float)width / (float)reqWidth); } } return inSampleSize; } |
Here inSampleSize will reduce the size and memory size of
an Bitmap.To use this method, first
decode withinJustDecodeBounds set to true, pass the options through
and then decode again using the newinSampleSize value and inJustDecodeBounds set
to false.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); } |
Memory over flow error is gone…….