Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know a Bitmap size from InputStream before creating the Bitmap?

Tags:

android

I need to scale an image before creating it and I want to do it only if it exceeds 1024KB (for example).

By doing the following I can scale the image but I only need to scale the ones that are bigger than the given size.

Bitmap bmImg = null;
InputStream is = url.openStream();
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 10;
bmImg = BitmapFactory.decodeStream(is,null,opts);

How can I get the size of the Bitmap? (I'm happy knowing the amount of bytes, not the size after decompressing).

Edit:

I'm trying this:

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bmImg=BitmapFactory.decodeStream(is,null,opts);
Log.e("optwidth",opts.outWidth+"");
Bitmap bmImg1 = BitmapFactory.decodeStream(is);

The first time I use the InputStream (is) to decode it with the "inJustDecodeBounds" works fine and I can get the Bitmap dimensions. The problem is that the second time I use it to actually decode the image, no image is shown.

What am I doing wrong?

like image 429
sergi Avatar asked Jan 08 '11 13:01

sergi


3 Answers

I'm a noob so I can't comment on monkjack's answer directly. The reason his answer is so slow is that it's copying one byte at a time. Using a buffer of even 1K will significantly improve performance.

InputStream in = getContentResolver().openInputStream(docUri);

ByteArrayOutputStream bos = new ByteArrayOutputStream();
int i;
byte[] buffer = new byte[1024];
while ((i = in.read(buffer)) != -1) {
    bos.write(buffer);
}
byte[] docbuffer = bos.toByteArray();
like image 129
Scott Roberts Avatar answered Nov 10 '22 15:11

Scott Roberts


If your're trying to prevent OutOfMemory or something else...

you can create a buffer with your picture data,

BitmapFactory.Options buffer = new BitmapFactory.Options();
buffer.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(photo, 0, photo.length, buffer);

Then you can get the size using buffer.outHeight, buffer.outWidth..

If you want to scale, you just use buffer.isSampleSize but i noticed you're setting there a "10" value... wich i think is wrong... sampleSize should get a 2^ value .. like 2,4,8,16 etc.

Finally after you're sampleSize setting, you can create the bitmap as always.

Bitmap bmp = BitmapFactory.decodeByteArray(photo, 0, photo.length, buffer);

hope to help you!

PS: SQS MY ENGLISH =(!!!

like image 3
Sergio A. Avatar answered Nov 10 '22 15:11

Sergio A.


If you know the format of the file you might be able to read the header of the file. Habitually the header contains the size and format of the image. And luckily for you, this is always the first bytes of the file.

It might not be possible for certain types.

PNG, JPEG, BMP, TGA

Just read about the header and some file you might have to guess the width first. For exemple, the PNG doesn't seem to include widht/height but you should be able to read the width and guess a height with the pixel size / ratio.

Edit: My bad I thought you wanted to scale using the dimension... Yeah ContentLenght should help but sometimes it will return 0 if the server doesn't set the right dimension in the http header. In that case you need to know the returned size. But anyway, you can save a bytearray and once everything is loaded just check the lenght of the array. if it's bigger than 1024kb then resize the image. And save it or do whatever you want with it.

like image 2
Loïc Faure-Lacroix Avatar answered Nov 10 '22 15:11

Loïc Faure-Lacroix