I'm trying to get the width and height of an image, which I load from an image I pick from the gallery.
For testing, I used images from the drawable folder, I used this code:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
Now I got a bitmap that doesn't come from my drawable folder I can't do this:
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
What would be the proper way to retrieve the w/h.
There is a similar method working with an InputStream: BitmapFactory.decodeStream.
Assuming you have a File with your image (exceptions ommitted) :
BitmapFactory.decodeStream(new FileInputStream(myImageFile), null, options);
(this method works for any InputStream)
Related
I have a drawable that I would like to render in different sizes on the fly, as opposed to setting the size in layout file. How might I do that? I am referring to the call
imageView.setImageResource(R.drawable.image);
Decode the resource as a bitmap with a resolution (and other options) specified, then tell the ImageView to show the bitmap:
BitmapFactory.Options options = new BitmapFactory.Options();
options.outHeight = XXXX;
options.outWidth = XXXX;
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
imageView.setImageBitmap(bm);
If you have a Uri and you need the Bitmap, you could theoretically do this
Bitmap troublinglyLargeBmp =
MediaStore.Images.Media.getBitmap(
State.mainActivity.getContentResolver(), theUri );
but it will crash every time,
so you do this .........
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
AssetFileDescriptor fileDescriptor =null;
fileDescriptor =
State.mainActivity.getContentResolver().openAssetFileDescriptor( theUri, "r");
Bitmap actuallyUsableBitmap
= BitmapFactory.decodeFileDescriptor(
fileDescriptor.getFileDescriptor(), null, options);
Utils.Log("'4-sample' method bitmap ... "
+actuallyUsableBitmap.getWidth() +" "
+actuallyUsableBitmap.getHeight() );
that's fantastic and is the working solution.
Notice the factor of "four" which tends to work well, in current conditions (2014) with typical camera sizes, etc. HOWEVER, it would be best to guess or learn exactly the size of the image data at theUri, and then using that information, intelligently choose that factor.
In short, how to correctly choose that scale factor when you load a Uri ?
Android experts, is this a well-known problem, is there a solution? Thanks from your iOS->Android friends! :)
See the Android guide to handling large bitmaps.
Specifically this section:
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;
EDIT
In your case, you'll replace the decodeResource line with:
BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
I need to get the width and height of a bitmap but using this gives an out of memory exception:
Resources res=getResources();
Bitmap mBitmap = BitmapFactory.decodeResource(res, R.drawable.pic);
BitmapDrawable bDrawable = new BitmapDrawable(res, mBitmap);
//get the size of the image and the screen
int bitmapWidth = bDrawable.getIntrinsicWidth();
int bitmapHeight = bDrawable.getIntrinsicHeight();
I read the solution at the question Get bitmap width and height without loading to memory but what would be the inputStream here?
You need to specify some BitmapFactory.Options as well:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
bDrawable will not contain any bitmap byte array. Taken from here: Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data prior to construction (and memory allocation) of the bitmap.
Use this
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
see http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
How to scale bitmaps at runtime to a very small size and then storing them in internal storage? how to call the scaled bitmaps into the program from the storage at runtime and if its not there, call it from drawable folder, scale it, write it to storage and then bind it to the view.
If you want to scale the bitmap you could use Bitmap.createScaledBitmap
To scale an arbitrary bitmap to 32x32 you could do it as follows:
Bitmap smallBitmap = Bitmap.createScaledBitmap( fullSizeBitmap, 32, 32, true );
You can use BitmapFactory.Options class to crop image to any size.
You can use following:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = 8; // 1/8th of actual image.
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Here, when you use a Bitmap, always call its bmp.recycle() method, since GC can't clear the memory held by Bitmap, if your bitmap is not getting garbage collected, then also you get the OME.
I would like to get a bitmap's dimensions in Android without reading the entire file.
I tried using the recommended inJustDecodeBounds and a custom InputStream that logged the read()s. Unfortunately based on this, the Android BitmapFactory appears to read a large amount of bytes.
Similar to:
Java/ImageIO getting image dimensions without reading the entire file? for Android, without using ImageIO.
You are right to use inJustDecodeBounds. Set it to true and make sure to include Options in decode. This just reads the image size.
There is no need to read a stream. Just specify the path in the decode.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(<pathName>, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
java.net.URL imageUrl = new java.net.URL("https://yourUrl.com");
HttpURLConnection connection = (HttpURLConnection)imageUrl.openConnection();
connection.connect();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(connection.getInputStream(), null, options);
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;