设置
我正在使用自定义RenderBox
进行绘制。
下面代码中的canvas
对象来自于paint
方法中的PaintingContext
。
绘图
我正在尝试通过使用Canvas.drawRect
逐个渲染像素。
需要指出的是,这些像素有时比它们实际占据的屏幕像素大,有时则更小。
for (int i = 0; i < width * height; i++) {
// in this case the rect size is 1
canvas.drawRect(
Rect.fromLTWH(index % (width * height),
(index / (width * height)).floor(), 1, 1), Paint()..color = colors[i]);
}
存储
我将像素存储为 List<List<Color>>
(上面的代码中为colors
)。我之前尝试过不同嵌套的列表,但在性能方面没有引起任何明显的差异。
我的Android模拟器测试设备的内存在用999x999
的图像填充列表时增加了282.7MB。请注意,它只是暂时增加了282.7MB
。大约半分钟后,增加会降至153.6MB
并保持不变(没有任何用户交互)。
渲染
使用999x999
的分辨率,上面的代码会导致GPU最大值为250.1 ms/frame
和UI最大值为1835.9 ms/frame
,这显然是不可接受的。尝试绘制999x999
的图像时,UI会冻结两秒钟,这应该很容易(我猜想),因为4k视频在同一设备上运行顺畅。
CPU
我不确定如何使用Android Profiler正确跟踪此问题,但在填充或更改列表时,即绘制像素时(上面的指标也是如此),CPU使用率从0%
增加到最高60%
。以下是AVD性能设置:
原因
我不知道从哪里开始,因为我甚至不确定我的代码的哪个部分导致了冻结。是内存使用还是绘图本身?
一般来说,我该怎么做?我做错了什么?我应该如何存储这些像素。
努力
我尝试了很多方法都没有帮助,我只想指出最显著的几个:
我尝试将List<List<Color>>
转换为 dart:ui
库中的 Image
,希望使用 Canvas.drawImage
。为了做到这一点,我尝试编码自己的 PNG,但是我无法渲染超过一行。然而,它看起来并没有提高性能。当尝试转换一个 9999x9999
的图像时,我遇到了内存不足异常。现在,我想知道视频是如何呈现的,因为任何 4k 视频都会比一个 9999x9999
的图像占用更多的内存,如果其中几秒钟在内存中。我尝试实现
image
包。然而,在完成之前我停止了,因为我注意到它不是用于 Flutter 而是用于 HTML。我不会从那里获得任何东西。这对于我将要得出的结论非常重要:我尝试 仅仅绘制而不存储像素,即使用
Random.nextInt
生成随机颜色。当尝试随机生成一个 999x999
的图像时,这导致了 GPU 最大值 为 1824.7 ms/frames
和 UI 最大值 为 2362.7 ms/frame
,这甚至更糟,特别是在 GPU 部分。
结论
在尝试使用Canvas.drawImage
进行渲染之前,我得出的结论是:Canvas.drawRect
不适用于此任务,因为它甚至无法绘制简单的图像。
在Flutter中如何实现这一点?
注释
这基本上就是我两个月前尝试询问的内容(是的,我已经尝试了那么长时间来解决这个问题),但我认为当时我没有正确表达自己,并且对实际问题的了解更少。
我可以正确呈现的最高分辨率约为
10k
像素。我需要至少1m
。我正在考虑放弃Flutter并转向原生可能是我的唯一选择。然而,我希望相信我只是完全错误地处理这个问题。我已经花了大约三个月的时间来尝试解决这个问题,但我没有找到任何有用的信息。
BMP
格式,而从原始 ARGB 数据进行编码相对较容易 - 尽管我不知道这样的 ARGB->BMP 编码和 BMP->Image 解码有多快... - pskink