在画布上绘制

3

我正在编写一款 Android 应用程序,它可以在 View 的 onDraw 事件中直接绘制到画布上。

我正在进行每个像素点的单独绘制,为此我使用类似以下的方法:

for (int x = 0; x < xMax; x++) {
  for (int y = 0; y < yMax; y++){
    MyColour = CalculateMyPoint(x, y);
    canvas.drawPoint(x, y, MyColour);
  }
}

这里的问题在于,由于CalculateMyPoint例程是一种昂贵的方法,所以绘制需要很长时间。
是否有更有效的方法来绘制到画布上?例如,我应该绘制到位图上,然后在onDraw事件中将整个位图绘制到画布上吗?或者,评估我的颜色并填充一个数组,onDraw方法可以使用该数组来绘制画布?
目前,我的应用程序的用户将能够更改影响画布绘制的参数。这非常缓慢。

CalculateMyPoint 处理起来为什么如此缓慢? - Adam
我有一个相当复杂的计算,用于计算任何给定像素使用的颜色。我只是想知道是否最好在View的onDraw事件之外的其他地方计算每个像素的颜色。 - Mattl
你必须逐个绘制每个像素吗?因为在Droid或Nexus One上有超过400k个像素,我觉得在CalculateMyPoint的调用次数中优化的机会比它的运行时间更多。 - jqpubliq
你能展示一下这段代码试图绘制的图像类型吗?肯定有比逐个绘制每个像素更高效的绘图方式。 - Eric Rowell
感谢您的评论。这是曼德博集合,我试图实现捏合缩放和支持深度缩放,但遇到了性能问题。我可能会在有时间的时候重新审视这个项目。 - Mattl
1个回答

5
正如人们所指出的,如果CalculateMyPixel()是昂贵的,那么调用150,000次(HVGA)或384,00次(WVGA)就会让你崩溃。
此外,尝试通过canvas.drawPoint()每次更新时绘制UI中的单个像素点只是最低效的方法之一。
如果您正在绘制单个像素,则几乎肯定要使用包含像素的某种离屏位图,然后使用简单的Canvas.drawBitmap()进行绘制。
然后,您可以决定管理该位图的最佳方法。 最简单的方法是仅制作所需大小的位图对象,并使用其中的API来填充它。
或者,有一个drawBitmap()版本,它采用原始整数数组,因此您可以直接填充它们以避免每个像素的方法调用。
现在,您可以将像素计算移出onDraw()方法,这需要快速才能拥有响应灵敏的UI,并在其他地方填充像素。也许您在初始化时计算它们一次。也许您计算它们,并在调用invalidate()之前对已更改的部分进行选择性更新(例如从(0,0)-(10,l0)的像素已更改,因此取当前位图并仅修改该区域)。如果计算像素确实本质上很慢,您可能需要创建一个单独的线程来完成这项工作(使用新像素更新位图,然后在UI上postInvalidate()以绘制它们)。
此外,现在您的像素位于位图中,您可以使用技巧使位图的大小更小,并在绘制到屏幕时进行缩放,从而让您花费更少的时间更新这些像素,同时仍然填充整个UI(尽管分辨率较低)。

谢谢,我想这都是常识了。目前,在我的OnDraw例程中使用代码初始化应用程序大约需要1分钟,超过1秒可能是不可接受的。这个调用可以使用像素数组初始化我的位图:public static Bitmap createBitmap (int[] colors, int width, int height, Bitmap.Config config)同样也是真的,我并不需要WVGA分辨率,所以我会尝试缩放。 - Mattl
我按照这些提示度过了晚上,将我的渲染时间从近一分钟缩短到了3秒钟!我认为通过进一步优化,我可以再节省一秒钟的时间。再次感谢hackbod。 - Mattl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接