简体   繁体   English

android快速像素访问和操作

[英]android fast pixel access and manipulation

I'm trying to port an emulator that i have written in java to android. 我正在尝试将我用java编写的模拟器移植到android。 Things have been going nicely, I was able to port most of my codes with minor changes however due to how emulation works, I need to render image at pixel level. 事情进展顺利,我能够通过微小的更改移植我的大部分代码,但由于仿真的工作方式,我需要在像素级渲染图像。

As for desktop java I use 至于我使用的桌面java

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

which allow me to get the reference to the pixel buffer and update it on the fly(minimize object creations) 这允许我获得对像素缓冲区的引用并动态更新它(最小化对象创建)

Currently this is what my emulator for android does for every frame 目前这是我的android模拟器为每一帧做的

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

}   

pixelsA is an array int[], pixelsA contains all the colour informations, so every frame it will have to create a bitmap object by doing pixelsA是一个数组int [],pixelsA包含所有颜色信息,因此每个帧都需要通过执行来创建一个位图对象

buffer = Bitmap.createBitmap(pixelsA, 256, 192, Bitmap.Config.RGB_565);

which I believe is quite expensive and slow. 我认为这是相当昂贵和缓慢的。

Is there any way to draw pixels efficiently with canvas? 有没有办法用画布有效地绘制像素?

One quite low-level method, but working fine for me (with native code): 一个非常低级的方法,但对我来说工作正常(使用本机代码):

Create Bitmap object, as big as your visible screen. 创建与可见屏幕一样大的Bitmap对象。 Also create a View object and implement onDraw method. 还要创建一个View对象并实现onDraw方法。

Then in native code you'd load libjnigraphics.so native library, lookup functions AndroidBitmap_lockPixels and AndroidBitmap_unlockPixels . 然后在本机代码中,您将加载libjnigraphics.so本机库,查找函数AndroidBitmap_lockPixelsAndroidBitmap_unlockPixels These functions are defined in Android source in bitmap.h. 这些函数在bitmap.h中的Android源中定义。

Then you'd call lock/unlock on a bitmap, receiving address to raw pixels. 然后你在位图上调用锁定/解锁,接收原始像素的地址。 You must interpret RGB format of pixels accordingly to what it really is (16-bit 565 or 32-bit 8888). 您必须根据实际情况(16位565或32位8888)解释RGB格式的像素。

After changing content of the bitmap, you want to present this on screen. 更改位图的内容后,您希望在屏幕上显示此内容。 Call View.invalidate() on your View . View上调用View.invalidate() In its onDraw , blit your bitmap into given Canvas . 在其onDraw ,将您的位图blit到给定的Canvas

This method is very low level and dependent on actual implementation of Android, however it's very fast, you may get 60fps no problem. 这个方法水平很低,并且依赖于Android的实际实现,但是它非常快,你可能得到60fps没问题。

bitmap.h is part of Android NDK since platform version 8, so this IS official way to do this from Android 2.2. bitmap.h是Android NDK自平台版本8以来的一部分,因此这是从Android 2.2执行此操作的官方方式。

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

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

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

Don't recreate the bitmap every single time. 不要每次都重新创建位图。 Try something like this: 尝试这样的事情:

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);
}

EDIT: as pointed out, you need to update the pixel buffer. 编辑:正如所指出的,您需要更新像素缓冲区。 And the bitmap must be mutable for that to happen. 并且位图必须是可变的才能实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM