2011-09-29 16 views
8

Estoy tratando de portar un emulador que he escrito en Java para Android. Las cosas han ido bien, pude cambiar la mayoría de mis códigos con pequeños cambios, sin embargo, debido a la forma en que funciona la emulación, necesito renderizar la imagen a nivel de píxel.android rápido acceso y manipulación de píxeles

En cuanto a Java Desktop utilizo

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

que me permiten obtener la referencia a la memoria intermedia de píxeles y actualizar sobre la marcha (minimizar creaciones de objetos)

Actualmente esto es lo que mi emulador para androide hace para cada trama

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

} 

pixelsA es una int array [], pixelsA contiene todas las informaciones de color, por lo que cada marco que tendrá que crear un objeto de mapa de bits haciendo

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

que creo que es bastante caro y lento.

¿Hay alguna manera de dibujar píxeles de manera eficiente con el lienzo?

+0

Es cierto que CreateBitmap es lento, es la copia de la memoria, e incluso la conversión de formato de píxeles en su caso! –

Respuesta

0

No vuelva a crear el mapa de bits cada vez. Intentar algo como esto:

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: como se ha señalado, es necesario actualizar la memoria intermedia de píxeles. Y el mapa de bits debe ser mutable para que eso suceda.

+0

Esto no funcionará. Bitmap inicializa su propio búfer de píxeles en createBitmap, sin llamarlo no actualizará los píxeles de Bitmap. –

10

Un método muy bajo nivel, pero trabajando bien para mí (con código nativo):

Crear Bitmap objeto, tan grande como su pantalla visible. También cree un objeto View e implemente el método onDraw.

Luego, en el código nativo cargaría libjnigraphics.so biblioteca nativa, funciones de búsqueda AndroidBitmap_lockPixels y AndroidBitmap_unlockPixels. Estas funciones se definen en la fuente de Android en bitmap.h.

Luego llamarías a bloqueo/desbloqueo en un mapa de bits, recibiendo dirección a los píxeles brutos. Debe interpretar el formato RGB de los píxeles según lo que realmente es (16 bits de 565 o 32 bits de 8888).

Después de cambiar el contenido del mapa de bits, desea presentarlo en la pantalla. Llame View.invalidate() en su View. En su onDraw, ajuste su mapa de bits en Canvas.

Este método es de muy bajo nivel y depende de la implementación real de Android, sin embargo, es muy rápido, puede obtener 60fps sin problemas.

bitmap.h es parte de Android NDK desde la plataforma de la versión 8, por lo que esta es la forma oficial de hacerlo desde Android 2.2.

4

Puede usar el drawBitmap method que evita crear un mapa de bits cada vez, o incluso como último recurso, dibujar los píxeles uno por uno con drawPoint.

+0

Intenté el método drawBitmap que toma int [] como su parámetro, proporciona un buen impulso al rendimiento sobre la creación de objetos de mapa de bits. Parece ser la única forma (creo) de lograr un rendimiento aceptable sin recurrir al código nativo. – afro100

+1

Es bueno saber que funcionó. Como dices, no hay nada tan rápido como volverse nativo, pero es mucho más complejo. –

0

si pixelsA ya es una matriz de píxeles (que es lo que iba a deducir de su declaración sobre que contiene los colores) a continuación, puedes hacerlas directamente sin convertir con:

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