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.
Related
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
I want to add a few ImageView in a linearLayout programmatically.
but application crashed for more than 2 images. its error is OutOfMemoryError.
String[] titleImages={"a","b","c","d","e","f","g"};
for (String title : titleImages){
InputStream inputStream = context.getAssets()
.open("titles"+"/"+title);
Drawable drawable = Drawable.createFromStream(inputStream, null);
inputStream.close();
ImageView imageView = new ImageView(_context);
imageView.setScaleType(ScaleType.FIT_XY);
imageView.setImageDrawable(drawable);
//more imageView set properties
LinearLayout shelf=findViewById(R.id.shelf);
//shelf is a LinearLayout
shelf.addView(imageView);
}
Use smaller images.
Or, use BitmapFactory.Options, an in particular its inSampleSize option, to downsample the images to something that is more appropriate for your screen size.
Or, use a third-party image-loading library, like Picasso, that can handle inSampleSize for you.
by using these methods you can resize the image as per your use.
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;
}
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;
}
i follow the steps in developers.android.com in best practice for Loading Large Bitmaps Efficiently, but i cant let the video thumbnail image apear in the imageview, what is the problem?
holder.imageHolder.setImageBitmap(decodeSampledBitmapFromResource(
aListData.get(position).path, 130, 100));
public Bitmap decodeSampledBitmapFromResource(String path,
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;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
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;
}
If it came from the developers.android.com it should work but i follow the guide but it didn't work.
reference: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
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.