Archie.bpgc
Archie.bpgc

Reputation: 24012

Android: bitmap.getByteCount() in API lesser than 12

When i searched for how to find the size of an image before saving it on the SD card, i found this:

bitmap.getByteCount();

but that method is added in API 12 and i am using API 10. So again i found out this:

getByteCount() is just a convenience method which does exactly what you have placed in the else-block. In other words, if you simply rewrite getSizeInBytes to always return "bitmap.getRowBytes() * bitmap.getHeight()"

here:

Where the heck is Bitmap getByteCount()?

so, by calculating this bitmap.getRowBytes() * bitmap.getHeight() i got the value 120000 (117 KB).

where as the image size on the SD card is 1.6 KB.

What am i missing? or doing wrong?

Thank You

Upvotes: 21

Views: 13510

Answers (7)

Enzokie
Enzokie

Reputation: 7415

Here is an alternative way:

public static int getBitmapByteCount(Bitmap bitmap) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1)
        return bitmap.getRowBytes() * bitmap.getHeight();
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
        return bitmap.getByteCount();
    return bitmap.getAllocationByteCount();
}

A statement from the IDE for getAllocationByteCount():

This can be larger than the result of getByteCount() if a bitmap is reused to decode other bitmaps of smaller size, or by manual reconfiguration. See reconfigure(int, int, Bitmap.Config), setWidth(int), setHeight(int), setConfig(Bitmap.Config), and BitmapFactory.Options.inBitmap. If a bitmap is not modified in this way, this value will be the same as that returned by getByteCount().

Upvotes: 2

NemesisDoom
NemesisDoom

Reputation: 596

Why don't you try dividing it between 1024? To get the KB instead of Bytes.

Upvotes: 0

pjco
pjco

Reputation: 3836

You are doing it correctly!

A quick way to know for sure if the values are valid, is to log it like this:

int numBytesByRow = bitmap.getRowBytes() * bitmap.getHeight();
int numBytesByCount = bitmap.getByteCount();
Log.v( TAG, "numBytesByRow=" + numBytesByRow ); 
Log.v( TAG, "numBytesByCount=" + numBytesByCount ); 

This gives the result:

03-29 17:31:10.493: V/ImageCache(19704): numBytesByRow=270000
03-29 17:31:10.493: V/ImageCache(19704): numBytesByCount=270000

So both are calculating the same number, which I suspect is the in-memory size of the bitmap. This is different than a JPG or PNG on disk as it is completely uncompressed.


For more info, we can look to AOSP and the source in the example project. This is the file used in the example project BitmapFun in the Android developer docs Caching Bitmaps

AOSP ImageCache.java

/**
 * Get the size in bytes of a bitmap in a BitmapDrawable.
 * @param value
 * @return size in bytes
 */
@TargetApi(12)
public static int getBitmapSize(BitmapDrawable value) {
    Bitmap bitmap = value.getBitmap();

    if (APIUtil.hasHoneycombMR1()) {
        return bitmap.getByteCount();
    }
    // Pre HC-MR1
    return bitmap.getRowBytes() * bitmap.getHeight();
}

As you can see this is the same technique they use

bitmap.getRowBytes() * bitmap.getHeight();

References:

Upvotes: 33

Rafael Sanches
Rafael Sanches

Reputation: 1823

the image on the sd card has a different size because it's compressed. on the device it will depend on the width/height

Upvotes: 0

Archie.bpgc
Archie.bpgc

Reputation: 24012

For now i am using this:

ByteArrayOutputStream bao = new ByteArrayOutputStream();
my_bitmap.compress(Bitmap.CompressFormat.PNG, 100, bao);
byte[] ba = bao.toByteArray();
int size = ba.length;

to get total no.of bytes as size. Because the value i get here perfectly matches the size(in bytes) on the image on SD card.

Upvotes: 6

steevoo
steevoo

Reputation: 631

may u can try this code

int pixels = bitmap.getHeight() * bitmap.getWidth();
int bytesPerPixel = 0;
switch(bitmap.getConfig()) {
case ARGB_8888:
bytesPerPixel = 4;
break;
case RGB_565:
bytesPerPixel = 2; 
 break;
case ARGB_4444:
bytesPerPixel = 2; 
 break;
case ALPHA_8 :
 bytesPerPixel = 1; 
 break;
}
 int byteCount = pixels / bytesPerPixel;

Upvotes: 1

darkNeuron
darkNeuron

Reputation: 31

Nothing is missing! Your codesnippet shows exact the implementation from Android-Source:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/graphics/Bitmap.java#Bitmap.getByteCount%28%29

I think the differences in size are the result of image-compressing (jpg and so on).

Upvotes: 2

Related Questions