android快速像素访问和操作

时间:2011-09-29 07:22:17

标签: android image android-canvas draw pixel

我正在尝试将我用java编写的模拟器移植到android。事情进展顺利,我能够通过微小的更改移植我的大部分代码,但由于仿真的工作方式,我需要在像素级别渲染图像。

对于桌面java,我使用

int[] pixelsA = ((DataBufferInt) src.getRaster().getDataBuffer()).getData(); 

允许我获取像素缓冲区的引用并动态更新(最小化对象创建)

目前这是我的Android模拟器为每一帧做的

@Override
public void onDraw(Canvas canvas)
{
    buffer = Bitmap.createBitmap(pixelsA, 256, 192, Bitmap.Config.RGB_565);
    canvas.drawBitmap(buffer, 0, 0, null);

}   

pixelsA是一个数组int [],pixelsA包含所有颜色信息,因此每个帧都必须通过

创建一个位图对象
buffer = Bitmap.createBitmap(pixelsA, 256, 192, Bitmap.Config.RGB_565);
我相信这是非常昂贵和缓慢的。

有没有办法用画布有效地绘制像素?

4 个答案:

答案 0 :(得分:10)

一种非常低级的方法,但对我来说工作正常(使用本机代码):

创建Bitmap对象,与可见屏幕一样大。 还要创建一个View对象并实现onDraw方法。

然后在本机代码中,您将加载libjnigraphics.so本机库,查找函数AndroidBitmap_lockPixelsAndroidBitmap_unlockPixels。 这些函数在bitmap.h中的Android源代码中定义。

然后你会在位图上调用锁定/解锁,接收原始像素的地址。您必须根据实际情况(16位565或32位8888)解释RGB格式的像素。

更改位图的内容后,您希望在屏幕上显示此内容。 在View.invalidate()上致电View。在onDraw中,将您的位图blit到给定的Canvas

这种方法水平很低,取决于Android的实际实现,但是速度非常快,你可能会得到60fps没问题。

bitmap.h是Android NDK自平台版本8以来的一部分,因此这是从Android 2.2执行此操作的官方方式。

答案 1 :(得分:4)

您可以使用drawBitmap method来避免每次创建位图,或者甚至作为最后的手段,使用drawPoint逐个绘制像素。

答案 2 :(得分:0)

不要每次都重新创建位图。尝试这样的事情:

Bitmap buffer = null;
@Override
public void onDraw(Canvas canvas)
{
    if(buffer == null) buffer = Bitmap.createBitmap(256, 192, Bitmap.Config.RGB_565);
    buffer.copyPixelsFromBuffer(pixelsA);
    canvas.drawBitmap(buffer, 0, 0, null);
}

编辑:正如所指出的,您需要更新像素缓冲区。并且位图必须是可变的才能实现。

答案 3 :(得分:0)

如果pixelsA已经是一个像素数组(这是我在你关于包含颜色的说法中推断出的那样)那么你可以直接渲染它们而不用转换为:

canvas.drawBitmap(pixelsA, 0, 256, 0, 0, 256, 192, false, null);