【问题标题】:How to find an image size that will not trigger an OutOfMemoryException in Android?如何在 Android 中找到不会触发 OutOfMemoryException 的图像大小?
【发布时间】:2018-12-15 01:12:49
【问题描述】:

我的应用使用设备相机拍摄图像,然后打开它以便用户执行一些处理。为此,我检查图像方向并在必要时旋转它,我这样做是这样的:

       Bitmap image = MediaStore.Images.Media.getBitmap(this.getContentResolver(), lastTaken);
        int rotation = getCameraPhotoOrientation(filePath);
        if (0 < rotation)
        {
            Matrix mx = new Matrix();
            mx.setRotate((float) rotation);
            image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), mx, true);
        }

此代码适用于大多数设备,但是在我一直使用的旧测试设备之一上,当图像旋转时它会导致OutOfMemoryException,大概是因为它试图在内存中保存图像的两个副本。

我怎样才能避免这种情况?

如果在此过程中没有一种简单的方法来防止出现问题,有没有一种方法可以测试我有多少可用内存并将相机使用的图像分辨率限制为可以留下足够的图像分辨率这个操作的空间?我已经指定了分辨率,所以我如何比较图像大小和可用内存以确定什么分辨率是安全的确实是一个问题。我的一个限制是用户所做的更改必须在原始图像上,因此编辑图像的较小副本不会剪切它,除非有一种简单的方法可以在存储的版本上反映这些更改。因此,将图像缩小到内存可以支持的大小无论如何都不会是一场灾难。

【问题讨论】:

标签: android memory-management android-bitmap


【解决方案1】:

您的图片尺寸是多少?您是否检查了应用程序中可能存在的内存泄漏?

无论如何,一种方法是,您可以尝试在创建新的第二个 Bitmap 内容后重用分配给第一个 Bitmap 的内存。 根据此处的 Android 文档 - https://developer.android.com/topic/performance/graphics/manage-memory

Android 3.0(API 级别 11)引入了 BitmapFactory.Options.inBitmap 字段。如果设置了这个选项,解码 采用 Options 对象的方法将尝试重用现有的 加载内容时的位图。这意味着位图的内存是 重用,从而提高性能,并删除两个内存 分配和解除分配。

您可以将您的位图图像设置为在创建新位图时回收。

【讨论】:

  • 这部分是相当独立的,问题不会出现在任何其他设备上,所以我认为它只是图像大小与内存的函数,这是一个非常好的提示inBitmap 选项。
【解决方案2】:

我找不到计算可用内存量和需要多少内存的方法,但在找到some other questions 关于这个主题后,我发现对我来说最好的解决方案是启用largeHeap 元素在application manifest - 为我解决了崩溃问题,尽管它没有回答问题,经过进一步阅读,我怀疑目前没有令人满意的方法来做到这一点。

【讨论】:

    猜你喜欢
    • 2018-09-30
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    相关资源
    最近更新 更多