I want to set a fullHD(1080x1920) image to ImageView.
I have searched but no efficient method.
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
Log.d("DUE","Options height: " + height + " - width: " + width);
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Or:
private Bitmap resize(int resId, int width, int height){
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}else{
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeResource(getResources(), resId, bmpFactoryOptions);
return bitmap;
}
I want to display the original image size, without reducing the size of image
Can you help me?
Thanks all!
You can use image loading libraries like Universal Image Loader, Fresco.
1) https://github.com/nostra13/Android-Universal-Image-Loader
2) https://github.com/facebook/fresco
3) https://guides.codepath.com/android/Displaying-Images-with-the-Fresco-Library
Both examples you posted are useful to reduce the image size (i.e. to save memory).
I want to display the original image size, without reducing the size of image
If you only want to set a image from resources, there are much simpler alternatives.
Assing the image in code to an ImageView:
ImageView img;
img.setImageResource(R.drawable.image);
Or create a Bitmap from your Resource:
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Or set your image in xml:
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/image"
android:scaleType="center"/>
you can use glide
Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.
full documantation
Downloading custom sizes with Glide allow to add hight & width of iamge
Glide's ModelLoader interface provides developers with the size of the view they are loading an image into and allows them to use that size to choose a url to download an appropriately sized version of the image.
Using appropriately sized image saves bandwidth, storage space on the device, and improves the performance of the app.
Related
I have one image which have color code of #AAA28B (170R,162G,139B). Now let's say current image size is 1200x1200 now I want to make it scale down at 600x600 so i use below code and get resulted in bitmap but the problem is its bitmap color code change to #ABA38C, So it RGB values increase to plus one compare to original image color and become (171R,163G,140B) how to prevent this?.
See attach a screenshot where the first image if original loaded directly from android drawable and other it loads by using following code.
private void loadImage(int width, int height){
Bitmap bitMapTest=BitmapFactory.decodeResource(getResources(),R.drawable.ic_test);
Log.i("IMAGE","Image format is"+ bitMapTest.getConfig().name()+
"Image size is"+ bitMapTest.hasAlpha() + "bitmap size is"+ bitMapTest.getHeight());
Bitmap decodeBitmap=decodeSampledBitmapFromResource(getResources(),R.drawable.ic_test,width,height);
Log.i("IMAGE","Image format is"+ decodeBitmap.getConfig().name()+
"Image size is"+ decodeBitmap.hasAlpha() + "bitmap size is"+ decodeBitmap.getHeight());
//adjust of alha deos not give me any help result remain same
//decodeBitmap=adjustOpacity(decodeBitmap);
mImgView.setImageBitmap(decodeBitmap);
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig= Bitmap.Config.ARGB_8888;
options.inScaled=false;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 2;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Here is orginal image :-
It seems like applying following code for scaledown working fine for the solid image like this.
Bitmap decodeBitmap=Bitmap.createScaledBitmap(sourceBitmap,width,height,false/*Make sure filter is false*/);
I know, there are a lot of similar questions in Stackoverflow. But I could not solve my problem.
I have some kind of jigsaw puzzle. The pictures in the Drawable-nodpi folder are 2500x1250.
I am trying to resize the images with the following code suggested:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
I call it like this:
(I call these codes several times.)
private Bitmap resizeImg (int rsm) {
Bitmap bmp = decodeSampledBitmapFromResource(getResources(),rsm,wdth,hght);
return bmp;
}
I need to use Matrix as the scaling of Imageview. But it's not the size I want. It works right without the Matrix.
I'm solving the Matrix problem like this:
Bitmap.createScaledBitmap
private Bitmap resizeImg (int rsm) {
Bitmap bmp = decodeSampledBitmapFromResource(getResources(),rsm,wdth,hght);
// return bmp;
Bitmap resized = Bitmap.createScaledBitmap(bmp, wdth,hght,true); //I get OutOfMemoryError this line.
return resized;
}
This insertion really solves my problem. But every day I get lots of OutOfMemoryError errors.
What do I need to do to fix this error? Please help me. Thank you.
1] Add largeHeap as true in android manifest to your application tag:
android:largeHeap="true"
2] Recycle your all used bitmaps,
Example:
bmp.recycle();
resized.recycle();
I have a set of image files stored in internal storage, each file size is about 750 KB. I need to create a 360 degrees animation like with this images, so, I load each image in a list, while I'm doing this process an out of memory exception appears.
I have been reading about bitmap processing on Android, but in this case is not about resize bitmap dimensions, the dimensions are OK (600, 450) because its a tablet application, is about image quality I think.
Is there a way to reduce the memory each bitmap takes?.
It is not possible without reducing image dimensions.
All images with the same dimensions require same amount of RAM, regardless it size on disk and compression. Graphics adapter don't understand different image types and compression and it needs only uncompressed raw array of pixels. And it size is constant
For example
size = width * height * 4; // for RGBA_8888
size = width * height * 2; // for RGB_565
So you should reduce image dimensions or use caching on the disk and remove bitmaps from the RAM that are currently invisible and reload from disk when needed.
There is a great resource on how to do this here:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Basically you need to load a bitmap at a different resolution using these two functions:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
Then set the image as follows:
imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(),
R.drawable.my_image_resource,
imageView.getWidth(),
imageView.getHeight()));
Hope that helps!
I have a list in my application that contains all the installed applications with their icons, I'm able to render the installed applications and the icons as well but it is consuming lot of memory as it loads the drawables(icons) of the installed applications into memory as well.
I want to scale down the icon and then load into memory just to reduce the memory usage of the application. Can anyone tell me how that can be achieved.
Note : if PNG format then it will not compress your image because PNG is a lossless format.
and applications icons are in PNG format
Any way to reduce the memory allocation for the icons??
Yeah it's all in the docs:
http://developer.android.com/training/displaying-bitmaps/index.html
Calculate your sample size, i.e. size of the bitmap you want:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
The decode your bitmap at this size:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
This should all be done off the UI thread:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
You can then cache the bitmaps so you don't have to do it more times than necessary:
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Use inSampleSize from BitmapFactory.Options
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; //Downsample 10x
I am trying to set bitmap of higher size to imageview of fixed height and width,
Imageview in xml
<ImageView
android:id="#+id/imgDisplay"
android:layout_width="320dp"
android:layout_height="180dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:contentDescription="#string/app_name" />
When i am using the following code error is avoided but the image appeared is blurred because of BitmapFactory.Options options,
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
options.inSampleSize = 4;
Bitmap myBitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+"/"+photo, options);
imgMainItem.setImageBitmap(myBitmap);
What else are the option available of setting a image of higher size and fixed height and width please help
Don't used a fixed sample size. Calculate the sample size you need first, like so:
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
Then, use it like so:
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+"/"+photo;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
Bitmap myBitmap = BitmapFactory.decodeFile(path, options);
imgMainItem.setImageBitmap(myBitmap);
width and height is your required width and height in pixels.
If your bitmap is a lot smaller than the size you want, you can't really scale it up without it being blurry. Use a higher-quality bitmap.