Decoding Bitmaps in Android with the Right Size

Decoding bitmaps in Android with the right size

You are on the right track, however you are trying to do two things at once: read the file in and scale it to the appropriate size.

The first step is to read the file to a Bitmap slightly bigger than you require, using BitmapFactory.Options.inSampleSize to ensure that you do not consume excessive memory reading a large bitmap when all you want is a smaller thumbnail or screen resolution image.

The second step is to call Bitmap.createScaledBitmap() to create a new bitmap to the exact resolution you require.

Make sure you clean up after the temporary bitmap to reclaim its memory. (Either let the variable go out of scope and let the GC deal with it, or call .recycle() on it if you are loading lots of images and are running tight on memory.)

Decoded bitmap results in larger size

I had a similar issue. When I downloaded images from web they used more space on the SD than they did when downloaded to my PC from browser. I think the issue is simply that BitmapFactory saves the images in a non optimzed format of some sort.

My workaround was to use following instead of the bitmapfactory:

    try {
try {
is = yourinputstream;
// Consider reading stream twice and return the bitmap.

os = youroutputstream;

byte data[] = new byte[4096];
int count;
while ((count = is.read(data)) != -1) {
os.write(data, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(is != null) {
is.close();
}
if(os != null) {
os.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}

Is this a correct way to get a bitmap's size before decoding it into memory?

You can select the bitmap configuration with BitmapFactory.Options.inPreferredConfig. This will allow you to specify a configuration where you know for sure how many bytes per pixel will be occupied by the Bitmap. I believe RGB_8888 is the default.

You can probably not 100% reliably prevent an OOM on a bitmap decode since you don't have a guarantee for a set amount of contiguous free space in memory for the allocation of the Bitmap. But you can certainly adjust your sample size and config to reduce the load.

How to know the right dimension to load a large Bitmap image in android?

As a suggestion ,

  1. You can define the approx : width and height of your imageview as a portion of
    device width and height in pixels. As ex:

    imageview width = 0.8 of device width  & imageview height = 0.4 of device height
  2. Then you can calculate the device width and height in pixels. There by you can get the actual required imageview size according to relevant portion.

  3. Then you can pass the calculated imageview width and height in to "decodeSampledBitmapFromResource" method.

Bitmap byte-size after decoding?

getRowBytes() * getHeight() seems to be working fine to me.

Update to my ~2 year old answer:
Since API level 12 Bitmap has a direct way to query the byte size:
http://developer.android.com/reference/android/graphics/Bitmap.html#getByteCount%28%29

----Sample code

    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
protected int sizeOf(Bitmap data) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
return data.getRowBytes() * data.getHeight();
} else {
return data.getByteCount();
}
}

Handling large Bitmaps

There is an option in BitmapFactory.Options class (one I overlooked) named inJustDecodeBounds, javadoc of which reads:

If set to true, the decoder will
return null (no bitmap), but the
out... fields will still be set,
allowing the caller to query the
bitmap without having to allocate the
memory for its pixels.

I used it to find out the actual size of the Bitmap and then chose to down sample it using inSampleSize option. This at least avoids any OOM errors while decoding the file.

Reference:

1. Handling larger Bitmaps

2. How do I get Bitmap info before I decode

Calculating appropriate image size in Android

I assume you're using a fixed value of 1024 for reqWidth and reqHeight. If this is the case, and you're displaying the images on screen, get the width and height of the screen and use these as reqWidth and reqHeight.

By using a hardcoded value of 1024, you could be loading an image up to 2047x2047px, which would be too large for the smaller devices.

Decode a part of Bitmap from file in Android

is it possible that there is a solution for this?

for example , BitmapRegionDecoder .

It should work for API10 and above...

Usage:

BitmapRegionDecoder.newInstance(...).decodeRegion(...)


Related Topics



Leave a reply



Submit