2011-09-29 86 views
8

我試圖移植一個模擬器,我已經寫在java到android。事情一直很好,我能夠移植我的大部分代碼,但由於模擬的工作原因,我需要在像素級渲染圖像。android快速像素訪問和操作

至於桌面Java我使用

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

這讓我獲得參考像素緩衝區和更新上飛(最小化對象的創建)

目前,這是我的什麼模擬器機器人確實對於每一幀

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

我認爲這是相當昂貴和緩慢。

有沒有什麼方法可以有效地用畫布繪製像素?

+0

真,createBitmap是緩慢的,它是內存拷貝,甚至是像素格式在你的情況下的轉換! –

回答

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

編輯:如指出,你需要更新像素緩衝區。位圖必須是可變的才能發生。

+0

這不起作用。位圖在createBitmap中初始化其自己的像素緩衝區,而不調用它將不會更新位圖的像素。 –

10

一個相當低的水平的方法,但做工精細,我(本機代碼):

創建Bitmap對象,大如你的可視屏幕。 也創建一個View對象並實現onDraw方法。

然後在本機代碼中,您將加載libjnigraphics.so本機庫,查找函數AndroidBitmap_lockPixelsAndroidBitmap_unlockPixels。 這些函數在Android源代碼中是在bitmap.h中定義的。

然後,你會調用位圖上的鎖定/解鎖,接收原始像素的地址。您必須相應地將RGB像素格式解釋爲它的真實含義(16位565或32位8888)。

更改位圖的內容後,您希望在屏幕上顯示此內容。 致電View.invalidate()在您的View。在其onDraw中,將您的位圖分成給定的Canvas

這種方法是非常低的水平和依賴於Android的實際實施,但它非常快,你可能會得到60fps沒有問題。

bitmap.h是自平臺版本8以來的Android NDK的一部分,所以這是官方的方式來從Android 2.2做到這一點。

4

您可以使用drawBitmap method避免每次創建一個位圖,或甚至作爲最後的手段,與drawPoint一個接一個地繪製像素。

+0

我嘗試了以int []作爲參數的drawBitmap方法,它在位圖對象創建時提供了很好的性能提升。這似乎是唯一的方法(我認爲)在不訴諸本地代碼的情況下達到可接受的性能。 – afro100

+1

很高興知道它的工作。就像你說的那樣,沒有什麼東西像原生的一樣快,但它要複雜得多。 –

0

如果pixelsA已經是像素陣列(這是我想從你的陳述推斷出含有色),那麼你可以使它們的情況下直接與轉換:

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