how to scale bitmaps - android

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.

Related

set size of image resource on the fly with call setImageResource

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);

Android - width and height of bitmap without loading it

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

Reducing load image time and RAM

i am loading some bitmap from the gallery using the following code:
bitmap = (BitmapFactory.decodeFile(picturePath)).copy(Bitmap.Config.ARGB_8888, true);
bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, screenHeight, true);
bitmapCanvas = new Canvas(bitmap);
invalidate(); // refresh the screen
Question:
It seems that it takes so long time to load an image by first decode fully and copy, and then making scaling to fit for the screen width and height. It really actually does not need to load the pic with full density because I would not let the user to enlarge the imported image anyway.
In that way, are there any method to reduce the load time and RAM? (directly load a scaled-down image) How to further modify the above coding?
It may be worth trying RGB_565 instead of ARGB_8888 if you don't have transparency.
just have found the answer for this reducing RAM and load time and avoid outofmemory error from other similar questions.
//get importing bitmap dimension
Options op = new Options();
op.inJustDecodeBounds = true;
Bitmap pic_to_be_imported = BitmapFactory.decodeFile(picturePath, op);
final int x_pic = op.outWidth;
final int y_pic = op.outHeight;
//The new size we want to scale to
final int IMAGE_MAX_SIZE= (int) Math.max(DrawViewWidth, DrawViewHeight);
int scale = 1;
if (op.outHeight > IMAGE_MAX_SIZE || op.outWidth > IMAGE_MAX_SIZE)
{
scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE /
(double) Math.max(op.outHeight, op.outWidth)) / Math.log(0.5)));
}
final BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
//Import the file using the o2 options: inSampleSized
bitmap = (BitmapFactory.decodeFile(picturePath, o2));
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

Scale down Bitmap from resource in good quality and memory efficient

I want to scale down a 500x500px resource to fit always a specific size which is determined by the width of the screen.
Currently I use the code from the Android Developers Site (Loading Large Bitmaps Efficiently), but the quality is not as good as I would use the 500x500px resource in a ImageView (as source in xml) and just scale the ImageView and not the Bitmap.
But it's slow and I want to scale the Bitmap, too, to be memory efficient and fast.
Edit: The drawable which I wanna scale is in the drawable folder of my app.
Edit2: My current approaches.
The left image is the method from Loading Large Bitmaps Efficiently without any modifications. The center image is done with the method provided by #Salman Zaidi with this little modification: o.inPreferredConfig = Config.ARGB_8888; and o2.inPreferredConfig = Config.ARGB_8888;
The right image is an imageview where the image source is defined in xml and the quality I wanna reach with a scaled bitmap.
private Bitmap decodeImage(File f) {
Bitmap b = null;
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
float sc = 0.0f;
int scale = 1;
//if image height is greater than width
if (o.outHeight > o.outWidth) {
sc = o.outHeight / 400;
scale = Math.round(sc);
}
//if image width is greater than height
else {
sc = o.outWidth / 400;
scale = Math.round(sc);
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
}
return b;
}
Here '400' is the new width (in case image is in portrait mode) or new height (in case image is in landscape mode). You can set the value of your own choice.. Scaled bitmap will not take much memory space..
Dudes, inSampleSize param is made for memory optimization, while loading a bitmap from resources or memory. So for your issue you should use this:
Bitmap bmp = BitmapFactory.decode...;
bmp = bmp.createScaledBitmap(bmp, 400, 400, false);
inSampleSizelets lets you to scale bitmap with descret steps. Scale ratios are 2,4 and so on. So when your use decoding with options, where inSampleSize=2 you loads a 250x250 bitmap from memory and then stretch it to 400x400
Check this training:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
It shows how to resize bitmaps efficiently

Get bitmap width and height without loading to memory

Im a newbie in android, So i would like to know is there any way to get the dimensions of a Bitmap without loading the bitmap into memory.??
You can set the BitmapFactory.Options with inJustDecodeBounds to get the image width and height without loading the bitmap pixel in memory
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, bitmapOptions);
int imageWidth = bitmapOptions.outWidth;
int imageHeight = bitmapOptions.outHeight;
inputStream.close();
For more details:
public boolean inJustDecodeBounds
Since: API Level 1 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.
http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inJustDecodeBounds

Categories

Resources