Android:有效地滚动画布的内容?

时间:2009-05-30 19:31:53

标签: android canvas

我想绘制一个实时更新的图表(从右边开始)。我能想到的最有效的方法是将x [0 .. width-2]中的所有内容复制为1像素,然后在x [width-1]处绘制新值。

我对Android没什么经验,但据我所知,Canvas根本不会对它的内容进行操作。我每次都需要重画整个画面吗?这涉及缩放和平滑,所以我担心它会很慢。

我应该绘制一个字节[] []然后使用它来绘制到屏幕上(每次都移动我的缓冲区内容)?

4 个答案:

答案 0 :(得分:1)

如果图形有界,请尝试将所有图形渲染到图像,然后将相关部分从该图像blit到画布。尽量避免在缓冲区中实际“移动”像素,因为这可能会在读取和写入之间引入依赖关系,并且可能会严重影响性能。实际上,从1缓冲区复制到另一个缓冲区并交替将哪一个缓冲到屏幕可能更好。最后,如果您最终必须手动处理像素,请确保以行而不是列的形式运行图像,并从行的开头开始以帮助进行缓存。

答案 1 :(得分:1)

关于表现,没有剖析,我们不能说。

可能是目标手机上的线条图是硬件加速的,您应该使用每帧的线条绘制图元从头开始绘制图形。

另一方面,图像缓冲区的直接像素操作将是:

创建尺寸合适的图片并将其清除为“background_color”。此图像需要具有setpixel()功能。

有一组值记录每个x时间的y,因此对于您知道上次绘制图形的位置的任何列。

将此“chart_image”和“chart_array”视为循环缓冲区。对于每个时间步骤:

Y = ...;
X = time_since_start % chart_width;
chart_image.setpixel(X,chart_array[X],background_color); // clear previous line
chart_array[X] = Y;
chart_image.setpixel(X,chart_array[X],foreground_color); // draw new plot

现在你需要搞砸它。你需要两次blit图像:

X = time_since_start % chart_width;
// the newest data is on the left of the chart_image but gets drawn on the right side of the output
blit(out_x+X,out_y, // destination coordinates
    chart_image,
    0,0, // top left of part of chart_image to blit
    X,chart_height); // bottom right of chart_image part
// the oldest data is on the right of the chart_image but gets drawn on the left side of the output
blit(out_x,out_y,
    chart_image,
    X,0,
    chart_width,chart_height);

如果你想使用线条而不是单个像素,事情变得更加棘手,但是drawline()而不是setpixel()也可以使用这种方法。

(不知道Android API的道歉;但这种方法是通用的。)

答案 2 :(得分:0)

只是一个你可能已经考虑过的想法,但我不会移动缓冲区的内容 - 我只是尝试使用它像循环缓冲区。保留当前列的索引,一旦你再次回到最左边的列,你可以在两个段中绘制目标 - 当前列的右侧是什么,然后是左侧的内容,包括最近填写的专栏。这样你就不必转移任何东西,每个屏幕刷新只有两个blits(位图副本)。如果那个位太慢,你仍然可以将它们总是画在第二个屏幕外的缓冲区中,然后一次性将整个屏幕全部打到屏幕上。当然,屏幕上有一个很大的快速,不是吗?

答案 3 :(得分:0)

因为我可以理所当然地认为你将图形数据存储在内存中,所以重绘它应该不是问题。每帧重绘一组点都不够密集。转移记忆将是密集的,它正在移动一切,而不仅仅是绘画你需要的东西。 最糟糕的情况,因为它是时间的函数,每列显示只有一个值,系统必须绘制的横向800像素/值。这是微不足道的。 你有没有想过这个? 编辑:记住,并不是系统必须绘制每个点,它只是利用内存,然后使用它的原语。不要认为它会迭代绘制点,转储到视频内存,然后再次。