众所周知,Android存在将位图数据存储在RAM存储器中的问题。我需要在视图上加载图像(来自13Mpx相机的照片),然后我需要能够放大和缩小图像。图像应该是可变的。现在它以这种方式实现:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
_bitmap = BitmapFactory.decodeFile(_path, options);
当我拍摄大照片(13或8 Mpx)程序时,“内存不足”错误。我需要一些解决这个问题的方法。我需要一些可以使用大图像加载和操作(缩放)的类。它需要等于或小于API-8。
我尝试过Universall Image Loader,但它没有缩放选项。有人知道如何解决这个问题吗?
答案 0 :(得分:2)
位图占用每像素4个字节==> 13MP等于52MB的内存。
您应该首先使用BitmapFactory.Options来获取大小。通过使用inJustDecodeBounds
,您可以获得具有所有元数据的Bitmap对象,但没有实际图像。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
然后计算屏幕所需的比例尺寸:
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);
}
中对此进行了解释
答案 1 :(得分:1)
答案 2 :(得分:1)
尝试使用此缩放位图
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
/*
* If set to a value > 1, requests the decoder to
* subsample the original image, returning a smaller
* image to save memory. The sample size is the
* number of pixels in either dimension that
* correspond to a single pixel in the decoded
* bitmap. For example, inSampleSize == 4 returns an
* image that is 1/4 the width/height of the
* original, and 1/16 the number of pixels. Any
* value <= 1 is treated the same as 1. Note: the
* decoder uses a final value based on powers of 2,
* any other value will be rounded down to the
* nearest power of 2.
*/
options.inSampleSize = 2;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(path, options);
答案 3 :(得分:1)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
要避免java.lang.OutOfMemory
例外,请在解码之前检查位图的尺寸,除非您完全信任该源为您提供可预测大小的图像数据,这些数据可以轻松地放入可用内存中。 Reference
答案 4 :(得分:0)
非常感谢所有人的答案。
我认为我应该使用inJustDecodeBounds选项并加载调整大小的位图,但是需要对这个有经验的人的问题有一个全新的看法。
我还考虑过使用Universal Image Loader来加载和缓存大型图像,以及像ScaleImageView这样的Zooming。
有something可以解决我的问题。部分加载位图。