带有位图的 Android 内存不足异常

标签 android memory memory-management bitmap out-of-memory

首先,我阅读了很多关于内存不足异常的帖子和文章,但没有一篇对我的情况有帮助。我想要做的是从 SD 卡加载图像,但将其缩放到精确的像素大小。

我先获取图片的宽高,计算样本量:

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

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

这是我获取样本大小的方法(尽管它并不真正相关):

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

现在我有了样本大小,我将图像从磁盘加载到近似大小(样本大小):

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

现在,我将我创建的这个位图缩放到我需要的确切大小并清理:

    // 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 

上面的步骤通常是得到我的内存不足异常。有谁知道从磁盘加载精确大小的位图以避免必须像上面那样创建两个单独的位图的方法吗?

此外,当用户第二次运行此代码(设置新图像)时,似乎会出现更多异常。但是,我确保卸载从位图中创建的可绘制对象,这样可以在再次运行此代码之前对其进行垃圾回收。

有什么建议吗?

谢谢, 尼克

最佳答案

在您的情况下,在执行第一次解码后无需创建中间位图。由于您正在绘制到 Canvas,因此您可以使用以下任一方法(以您认为最方便的方法为准)将图像缩放到理想尺寸。

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

drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

关于带有位图的 Android 内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15030542/

相关文章:

javascript - 函数在内存中的大小

objective-c - 如果在 Objective-c 中作为参数传递,引用是否仍然很弱?

iphone - 自动释放对象的 Objective-C 成员初始化

memory-management - 为什么删除一半键时redis内存使用量没有减少

iphone - 清除 MKMapView 的图 block 缓存吗?

android - 跨平台(iOS-Android)xmpp请求

Android 应用程序在未运行时崩溃

链表中的连续动态内存分配

android - 来自 Android 网站的相机 Intent 不起作用 - Android

android - 在多模块 Android 项目中找不到 Kotlin typealias