2011-09-29 12 views
8

Sto provando a eseguire il porting di un emulatore che ho scritto in java su Android. Le cose sono andate bene, sono stato in grado di trasferire la maggior parte dei miei codici con piccole modifiche, tuttavia a causa di come funziona l'emulazione, ho bisogno di renderizzare l'immagine a livello di pixel.accesso e manipolazione veloce dei pixel android

Per quanto riguarda Java Desktop che uso

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

che mi permetta di ottenere il riferimento al buffer pixel e aggiornare al volo (ridurre al minimo le creazioni di oggetti)

Attualmente questo è ciò che il mio emulatore per android fa per ogni fotogramma

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

} 

pixelsA è un int array [], pixelsA contiene tutte le informazioni di colore, quindi ogni frame sarà destinato a creare un oggetto bitmap facendo

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

che credo sia piuttosto costoso e lento.

C'è un modo per disegnare in modo efficiente i pixel con la tela?

+0

vero, CreateBitmap è lento, è la copia di memoria, e anche la conversione di formato pixel nel tuo caso! –

risposta

0

Non ricreare la bitmap ogni volta. Provare qualcosa di simile:

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: come ha sottolineato, è necessario aggiornare il buffer dei pixel. E la bitmap deve essere modificabile affinché ciò accada.

+0

Questo non funzionerà. Bitmap inizializza il proprio buffer di pixel in createBitmap, non chiamandolo non aggiornerà i pixel di Bitmap. –

10

Un metodo molto di basso livello, ma lavorando bene per me (con codice nativo):

Creare Bitmap oggetto, grande come lo schermo visibile. Creare anche un oggetto View e implementare il metodo onDraw.

Quindi nel codice nativo si carica libreria nativa libjnigraphics.so, funzioni di ricerca AndroidBitmap_lockPixels e AndroidBitmap_unlockPixels. Queste funzioni sono definite nell'origine Android in bitmap.h.

Quindi chiameresti il ​​blocco/sblocco su una bitmap, ricevendo l'indirizzo a pixel non elaborati. È necessario interpretare il formato RGB dei pixel in base a ciò che è realmente (16 bit 565 o 32 bit 8888).

Dopo aver modificato il contenuto della bitmap, si desidera visualizzarlo sullo schermo. Chiama il View.invalidate() sul tuo View. Nella sua onDraw, blitare la bitmap nel dato Canvas.

Questo metodo è di livello molto basso e dipende dall'attuale implementazione di Android, tuttavia è molto veloce, non è possibile ottenere 60fps.

bitmap.h fa parte di Android NDK dalla versione piattaforma 8, quindi questo è il modo ufficiale per farlo da Android 2.2.

4

È possibile utilizzare drawBitmap method che evita di creare una Bitmap ogni volta, o anche come ultima risorsa, disegnare i pixel uno per uno con drawPoint.

+0

Ho provato il metodo drawBitmap che accetta int [] come parametro, offre un buon incremento delle prestazioni rispetto alla creazione di oggetti bitmap. Sembra essere l'unico modo (credo) per ottenere prestazioni accettabili senza ricorrere al codice nativo. – afro100

+1

Buono a sapersi, ha funzionato. Come dici tu, non c'è niente veloce come diventare nativi, ma è molto più complesso. –

0

se pixelsA è già una matrice di pixel (che è quello che vorrei dedurre dalla sua dichiarazione circa che contiene i colori), allora si può semplicemente rendere direttamente senza conversione con:

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