在Android中加载大图像

问题描述:

据了解,Android在将位图数据存储在RAM内存方面存在问题。我需要在视图中加载一张图片(来自13Mpx相机的照片),然后我需要能够放大和缩小图片。图像应该是可变的。现在,它是这样实现:在Android中加载大图像

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inMutable = true; 
_bitmap = BitmapFactory.decodeFile(_path, options); 

当我采取一个大的照片(13或8 MPX)PROGRAMM与“内存不足”的错误粉碎。我需要解决这个问题。我需要一些能够加载和操作(缩放)大量图像的类。它需要等于或小于API-8。

我试过Universall Image Loader,但它没有缩放选项。有人知道如何解决这个问题的任何想法?

+0

可能重复的[高分辨率图像 - OutOfMemoryError](http://stackoverflow.com/questions/18385362/high-resolution-image-outofmemoryerror) –

我建议使用Square的Picasso库。和PhotoView用于图像缩放。

尝试此用于缩放的位图

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); 

位图占用每像素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); 
} 

这是所有在Developer Guide解释

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

非常感谢所有您所有的答案。

我认为我应该使用inJustDecodeBounds选项和加载调整大小的位图,但需要一个新的看法,这个问题更有经验的人。

我也考虑过使用Universal Image Loader来加载和缓存大图像以及类似ScaleImageView的缩放图像。

something可以解决我的问题。部分加载位图。