Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android fast pixel access and manipulation

I'm trying to port an emulator that i have written in java to 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

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

@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

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?

like image 393
afro100 Avatar asked Sep 29 '11 07:09

afro100


1 Answers

One quite low-level method, but working fine for me (with native code):

Create Bitmap object, as big as your visible screen. Also create a View object and implement onDraw method.

Then in native code you'd load libjnigraphics.so native library, lookup functions AndroidBitmap_lockPixels and AndroidBitmap_unlockPixels. These functions are defined in Android source in bitmap.h.

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).

After changing content of the bitmap, you want to present this on screen. Call View.invalidate() on your View. In its onDraw, blit your bitmap into given 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.

bitmap.h is part of Android NDK since platform version 8, so this IS official way to do this from Android 2.2.

like image 189
Pointer Null Avatar answered Oct 26 '22 12:10

Pointer Null