修复 Bitmap.createBitmap 方法中内存不足异常的方法

问题描述 投票:0回答:1

我有以下代码将视图转换为位图以将其发送以进行打印。 它正在抛出 OutOfMemoryError Bitmap.createBitmap:

无法分配 43899852 字节的分配,其中有 9531608 个空闲字节和 9MB,直到 OOM

是否有可能划分问题,创建更小的位图并将它们组合起来,或者其他一些技巧?

 private fun loadBitmapFromView(context: Context, v: View): Bitmap {
    val dm = context.resources.displayMetrics
    v.measure(
            View.MeasureSpec.makeMeasureSpec(dm.widthPixels, View.MeasureSpec.EXACTLY),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    )
    v.layout(0, 0, v.measuredWidth, v.measuredHeight)
    val returnedBitmap = Bitmap.createBitmap(
            v.measuredWidth,
            v.measuredHeight, Bitmap.Config.ARGB_8888
    )
    val c = Canvas(returnedBitmap)
    v.draw(c)
    return returnedBitmap

}

android out-of-memory android-bitmap
1个回答
0
投票

我仍在尝试这个,但似乎限制可能取决于操作系统版本和硬件(较旧的操作系统版本可能会在 VM 堆中创建位图,该位图要小得多)

在我的 Android 10 设备上,位图的限制是 2Gb,因为它似乎是从本机内存分配的,而不是从 VM 的内存分配的(用它做事可能会使用 VM 内存,然后可能会应用下限)

因此,仅创建位图 26000 x 20000 成功 (1.9Gb) 已接近此设备的极限。

但是我对解决类似问题的想法。

  1. 使用

    Bitmap.Config.RGB_565
    这会将所需的内存减半(每个像素 2 字节而不是 4 字节)但这会影响颜色质量,但这对您来说可能没问题。 (这允许您创建高分辨率位图,不确定它们的外观)

  2. 创建缩小版。如果您创建缩小版本,普通打印机甚至屏幕可能不会被注意到。 例如以测量视图的一半大小创建位图,然后在画布上设置比例以按该比例绘制。

一个缺点是您似乎无法预先捕获这些错误,因此很难在 OOM 之后处理它们并选择替代策略。

(如果我的实验取得了一些成功,我会尝试更新这个)

© www.soinside.com 2019 - 2024. All rights reserved.