出的Andr​​oid位图内存异常 [英] Android out of memory exception with bitmaps

查看:179
本文介绍了出的Andr​​oid位图内存异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我看了一下内存不足异常很多帖子和文章,但他们都没有跟我的情况有帮助。我正在试图做的是从SD卡中加载图像,但它扩展到一个确切的像素大小。

First off, I have read many posts and articles about out of memory exceptions but none of them have helped with my situation. What I'm trying to do is load an image from the sd card but scale it to an exact pixel size.

我首先获取图像的宽度和高度,并计算出试样尺寸:

I first get the width and height of the image and calculate the sample size:

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(backgroundPath, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, getWidth(), getHeight());

下面是如何我得到的样本量(虽然它不是真正相关):

Here's how I get the sample size (although its not really relevant):

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;

    // NOTE: we could use Math.floor here for potential better image quality
    // however, this also results in more out of memory issues
    if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }

    return inSampleSize;
}

现在我有一个样本大小,我从磁盘映像加载到一个近似的尺寸(样本量):

Now that I have a sample size I load the image from disk to an approximate size (sample size):

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    options.inPurgeable = true;
    Bitmap bmp = BitmapFactory.decodeFile(backgroundPath, options);

现在,我这个扩展位图,我创建的确切大小,我需要清理工作:

Now, I scale this bitmap that I have created to the exact size I need and clean up:

    // scale the bitmap to the exact size we need
    Bitmap editedBmp = Bitmap.createScaledBitmap(bmp, (int) (width * scaleFactor), (int) (height * scaleFactor), true); 

    // clean up first bitmap
    bmp.recycle();
    bmp = null;
    System.gc();    // I know you shouldnt do this, but I'm desperate 

以上步骤通常得到我的内存溢出异常。有谁知道一种方法从磁盘加载一个确切大小的位图,以避免创建两个单独的位图,像上面?

The above step is usually get my out of memory exception. Does anyone know a way to load an exact size bitmap from disk to avoid having to create two separate bitmaps like above?

另外,好像当用户运行的第二次code(设置一个新的图像)更多发生异常。不过,我一定要卸载该由这使得它成为这个code之前收集的垃圾再次运行该位创建的绘制。

Also, it seems like more exceptions occur when the user runs this code for a second time (sets a new image). However, I make sure to unload the drawable that was created from the bitmap which allows it to be garbage collected before this code is run again.

有什么建议?

谢谢,
尼克

推荐答案

在你的情况没有必要你已经进行了第一次去code之后形成的中间位。既然你要画到画布,您可以使用以下两种方法(无论您找到最方便)将图像缩放到完美的大小。

In your case there's no need to create the intermediate bitmap after you've performed the first decode. Since you're drawing to to a Canvas, you can use either the following methods (whichever you find most convenient) to scale the image to the perfect size.

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)

drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

这篇关于出的Andr​​oid位图内存异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆