,以獲得與每個像素bytesPerPixel
字節偏移buffer.array()
對於給定像素x
,y
大小width
X height
的圖像中,使用以下公式:
offsetForPixel = (y * width + x) * bytesPerPixel
在換句話說,數組中的第一個元素是左上角的像素,以下元素是主要行。像素的所有數據都存儲在相鄰的字節中,並且不會根據通道進行分散。這是上面1,2和4的答案。現在讓我們來討論3,這是事情變得複雜的地方。
您使用Bitmap.copyPixelsToBuffer()獲得的是Android低級繪圖庫skia使用的原始位圖數據表示。這有三個顯著後果:
- 通道順序取決於字節序
- 通道預乘阿爾法
- 通道如何裝入包含數據類型是可配置的
最後如果您想檢查單個像素,那麼使用會很尷尬,因爲您根本無法知道skia是如何配置爲打包通道的。作爲一個實驗,試試這個代碼:
int inputPixel = 0x336699cc;
int[] pixels = new int[] { inputPixel };
Bitmap bm = Bitmap.createBitmap(pixels, 1, 1, Config.ARGB_8888);
ByteBuffer bb = ByteBuffer.allocate(4);
bm.copyPixelsToBuffer(bb);
Log.i("TAG", "inputPixel = 0x" + Integer.toHexString(inputPixel));
for (int i = 0; i < 4; i++) {
String byteString = "0x" + Integer.toHexString(bb.array()[i] & 0xff);
Log.i("TAG", "outputPixel byte " + i + " = " + byteString);
}
當我運行的是,我得到這樣的輸出:
I/TAG (1995): inputPixel = 0x336699cc
I/TAG (1995): outputPixel byte 0 = 0x14
I/TAG (1995): outputPixel byte 1 = 0x1f
I/TAG (1995): outputPixel byte 2 = 0x29
I/TAG (1995): outputPixel byte 3 = 0x33
我們可以看到,我們正在處理的大端,將內存中表示爲預先倍增,並且這些通道已經從ARGB重新排列到RGBA(在skia源代碼中的動機與OpenGL在內存中的表示相同)。
如果你想讀取像素數據,我建議你使用Bitmap.getPixels()來代替。涉及到一些複製,但至少API指定了返回數據的格式。