how to sample the bitmap for memory management in android? - android

i have made a demo for image editing,I am facing issue when i pass the image to another activity(Grow heap size),and my app crashed,Please tell me how cani sample and resize my bitmap directly (not from resources) to solve memory issue ,My code is as below:
code
if (Global.photo_editor_bitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Global.photo_editor_bitmap.compress(Bitmap.CompressFormat.PNG,
100, stream);
byte[] byteArray = stream.toByteArray();
i = new Intent(PhotoEditor.this, Enhance.class);
i.putExtra("bitmap_image", byteArray);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
} else {
Toast.makeText(getApplicationContext(), "No Image", 1).show();
}
static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
int inSampleSize = 1; // Default subsampling size
// See if image raw height and width is bigger than that of required
// view
if (options.outHeight > reqHeight || options.outWidth > reqWidth) {
// bigger
final int halfHeight = options.outHeight / 2;
final int halfWidth = options.outWidth / 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;
}
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);
}
I got solution of decodebitmapFromresources,But my bitmap is available,SO how to use this direclty.

I have the same problem the app gets crashed and showing message in log for heap size, allocation size and bitmap size, what i have done is checked the device width & height and on the basis of that scaled the bitmap or calculate sample size.
int screenHeight = getResources().getDisplayMetrics().heightPixels;
int screenWidth = getResources().getDisplayMetrics().widthPixels;
get the width and height and then put it in reqWidth and reqHeight

Related

OutOfMemory error while loading Images using Sampling

I am displaying Images on RecyclerView in ImageView with dimensions as 50*50. I have used the guide Guide given by google to display Bitmaps using Scaling etc.Along, with guide I have also use Glide library to set Image.The code to Sample Image is
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;
}
This is a code to DecodeSampleBitmap
public static Bitmap decodeSampledBitmapFromResource(int reqWidth, int reqHeight,byte[] bytes) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inInputShareable=true;
options.inPurgeable=true;
// BitmapFactory.decodeResource(res, resId, options);
BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(bytes,0,bytes.length,options);
}
This is code to set Image to ImageView using Glide
BitmapFactory.Options options = new BitmapFactory.Options();
BitmapFactory.decodeByteArray(imageBytes,0,imageBytes.length,options);
options.inJustDecodeBounds = true;
options.inInputShareable=true;
options.inPurgeable=true;
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Drawable d=new BitmapDrawable(getResources(),decodeSampledBitmap(50,50));
Glide.with(getActivity())
.load(d).into(offerBinding.restImg);
In-spite of doing all this calculations I am always getting OutOfMemory error and app get crashed when more Images are load. How to resolve this ?
For your base64String to Imageview use it like this
Glide.with(context)
.load(Base64.decode(base64String, Base64.DEFAULT))
.placeholder(R.drawable.placeholder) // load at start
.error(R.drawable.imagenotfound) // in case of error
.override(50,50)
.skipMemoryCache(true)
.into(rowImageView);
I Hope it will works fine

OutOfMemoryError android Bitmap listview

In my application I use an SQLite database to store the data of a lot of images. Some images can be up to 600x600 pixels. I use a custom list to create the bitmaps. I know there is a method bitmap.recycle(); but I'm not sure how to use that with a listview.
Here is the solution to handle bitmaps in android
First, you should calculate the sampleBitmapSize of the bitmap ( to load the lower version of the same bitmap )
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);
}
Below is the util function to calculate InSampleSize ( an integer that defines the value (rating) of quality of a bitmap).
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;
}
}
Log.i("ImageUtil", "InSampleSize: "+inSampleSize);
return inSampleSize;
}

Android Bitmap for Performance

I have this
Bitmap appWidgetBitmap = Bitmap.createBitmap(availableWidth, availableHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(appWidgetBitmap);
And in the log console I see this
"dalvikvm-heap Grow heap (frag case) to......byte allocation
How can I make Bitmap with the lowest resources possible?
I saw something on BitmapFactory, but how to do it because the code above is createBitmap, not from resources.
Use below methods for resizing the image as aspect ratio:
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;
// BitmapFactory.decodeResource(res, resId, options);
return Bitmap.createScaledBitmap(
BitmapFactory.decodeResource(res, resId, options), reqWidth,
reqHeight, true);
}
Then decode your image into bitmap format and set into the Canvas:
Bitmap src = decodeSampledBitmapFromResource(getResources(),
R.drawable.ic_bg_box, imgWidth, imgHeight);
Canvas canvas = new Canvas(src);
I hope this will help you.

Android: failed to open 3 times a very large image

I am trying to load a very large image in my app (2000x3000 and 600kb). I manage to make it open with this code:
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;
// 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;
}
But I get an OutOfMemoryError when I open it 3 times or try to open another activity. How I can fix it?
thanks
"But I get an OutOfMemoryError when I open it 3 times or try to open
another activity. How I can fix it?"
Release your resources! Call bitmap.recycle() and null the bitmap.

Get memory leak when decode small jpg image in Android

I decode a small jpg image to bitmap in my app.
The image is only 40K.
I use these methods:
public Bitmap decodeSampledBitmapFromResource(String pathName,int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp=BitmapFactory.decodeFile(pathName, options);
return bmp;
}
public 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;
}
and when the program goes to:
Bitmap bmp=BitmapFactory.decodeFile(pathName, options);
I get GC_Concurrent in the LogCat,
why?
GC_CONCURRENT per se is not bad. It's just a status message from the garbage collector doing its job. Image decoding involves memory allocations and it's normal to see garbage collector running.

Categories

Resources