我有以下代码将视图转换为位图以将其发送以进行打印。 它正在抛出 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
}
我仍在尝试这个,但似乎限制可能取决于操作系统版本和硬件(较旧的操作系统版本可能会在 VM 堆中创建位图,该位图要小得多)
在我的 Android 10 设备上,位图的限制是 2Gb,因为它似乎是从本机内存分配的,而不是从 VM 的内存分配的(用它做事可能会使用 VM 内存,然后可能会应用下限)
因此,仅创建位图 26000 x 20000 成功 (1.9Gb) 已接近此设备的极限。
但是我对解决类似问题的想法。
使用
Bitmap.Config.RGB_565
这会将所需的内存减半(每个像素 2 字节而不是 4 字节)但这会影响颜色质量,但这对您来说可能没问题。
(这允许您创建高分辨率位图,不确定它们的外观)
创建缩小版。如果您创建缩小版本,普通打印机甚至屏幕可能不会被注意到。 例如以测量视图的一半大小创建位图,然后在画布上设置比例以按该比例绘制。
一个缺点是您似乎无法预先捕获这些错误,因此很难在 OOM 之后处理它们并选择替代策略。
(如果我的实验取得了一些成功,我会尝试更新这个)