Decode File From SdCard android to avoid out of memory error due to large bitmap or setImageURI
Avoid outof memory error for selecting large image file from sdcard or from resource. how can i tackle with this problem?
为避免从位图中选择SD卡中的文件时出错或使用setImageURI到SD卡,请使用以下方法:
public static Bitmap decodeScaledBitmapFromSdCard(String filePath,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, 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) {
// 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;
}
you can use inSampleSize to reduce memory occupied.
Here is code
public static Bitmap decodeAndResizeFile(File f) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 70;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
Here, it will decode image using inSampleSize
and this code will find the best inSampleSize
values for you.
It worked Fine for me.
if you don't want to use above code, You can also use bitmap.recycle()
and System.gc()
to release unused memory.But, above one works fine for me. You can use either of the two.
objbitmap.recycle();
objbitmap = null;
System.gc();
Hope, this may solve the issue!
This depends on if you know what size you want to end up with or not.
If you know the size:
See the answer by Android_Craker. It is a solid approach to the problem.
If you don't know the size:
In this case you want the image to be as large as will fit in memory. The solution is to loop over the downsample until you find a size that fits: BitmapFactory.Options options = new BitmapFactory.Options();
boolean done = false;
int downsampleBy = 1;
Bitmap bitmap = null;
while (!done) {
options.inSampleSize = downsampleBy++;
try {
bitmap = BitmapFactory.decodeFile(filePath, options);
done = true;
catch (OutOfMemoryError e) {
// Ignore. Try again.
}
}
链接地址: http://www.djcxy.com/p/16626.html
上一篇: 在ListView中延迟加载图像