我在使用ColorMatrixColorFilter修改位圖中的彩色像素時遇到困難。如果我使用本地文件系統(jpg)的位圖,它可以工作。但是,如果我使用從Buffer創建的位圖,則畫布上不會繪製任何內容。使用ColorMatrixColorFilter時畫布不繪製位圖
特別地,我使用以下代碼來創建嘉洛斯:
float matrix[] = new float[] {
0, 0, 1, 0, 0,
0, 1, 0, 0, 0,
1, 0, 0, 0, 0,
0, 0, 0, 1, 0
};
rbSwap = new ColorMatrix(matrix);
paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setColorFilter(new ColorMatrixColorFilter(rbSwap));
以上是用於創建用於交換的紅色和藍色的顏色的ColorMatrixColorFilter。
如果我用下面的代碼創建位圖,它的工作原理:
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.picture);
如果我創建使用下面的代碼位圖,沒有什麼是永遠畫到畫布:
bitmap = Bitmap.createBitmap((int) width, (int) height,
Bitmap.Config.ARGB_8888);
srcBuffer = ByteBuffer.wrap(data);
srcBuffer.rewind();
bitmap.copyPixelsFromBuffer(srcBuffer);
我onDraw()看起來像下面這樣:
public void onDraw(Canvas canvas) {
canvas.drawBitmap(spicebmp, offsetX, offsetY, paint);
}
如果我沒有設置colorfilter,位圖呈現在我的畫布上。如果我設置了colorfilter,它只是一個黑色的屏幕 - 沒有任何東西可以呈現。如果我使用jpg位圖而不是通過緩衝區創建的位圖,則會使用交換的紅色/藍色繪製。
我將矩陣更改爲與單位矩陣相同,並且位圖呈現正確。如果我改變矩陣中的任何一個浮點數(如1s到.5s或0),則不會繪製任何內容。
我也檢查過,以確保位圖有足夠的「字節」來表示位圖。 bitmap.byteCount()== srcBuffer.limit()是真的 - 所以我的緩衝區中的字節與我傳入的寬度/高度應該存在的字節相同。
我試了一下/ catch對於onDraw期間的任何異常以及通過logcat輸出,但沒有看到任何東西。我在Android位圖的繪製代碼戳四周,看到以下內容:
// nothing to draw
if (fClip->isEmpty() ||
bitmap.width() == 0 || bitmap.height() == 0 ||
bitmap.getConfig() == SkBitmap::kNo_Config ||
(origPaint.getAlpha() == 0 && origPaint.getXfermode() == NULL)) {
return;
}
我沒有跟蹤到核心的C++代碼的能力,因此,如果這是一個觸發我不能告訴。但我知道我的位圖的寬度和高度都是非零值(它們分別是800和600),我知道我的位圖在創建時被設置爲ARGV_8888類型,並且同樣的畫圖對象用於裝入jpg從磁盤(工作的那個)和我使用copyPixelsFromBuffer()創建的那個。
所以我不知道我在做什麼錯。我認爲它是位圖中與colorFiltering不兼容的一些標誌或屬性,但它只是一個適當大小的簡單ByteBuffer,類型爲ARGB_8888。當然,使用完全相同的代碼(繪畫對象等)來設置過濾器。
那麼還有什麼我需要做的位圖嗎?使用ColorMatrix/Filter?
我已經縮小了這個問題。我發現alpha通道字節總是被設置爲0(我的位圖是xRGB格式而不是ARGB)。當我在沒有ColorMatrix的情況下繪製它時,似乎Android忽略了字節字節。然而,當我使用ColorMatrixColorFilter來渲染它時,它將Alpha字節設置爲0,因此不會呈現任何內容,而是「黑色」。 我改變了ColorMatrix,使得最後的五個浮點值是:0,0,0,0,255,期望矩陣總是會導致alpha通道的255。如果alpha字節爲0,則A'= p * R + q * G + r * B + s * A + t不起作用。 – BJV