以Sylvain Ratabouil Android NDK(第2版)爲例,它從相機獲取圖像預覽並自然處理,從YUV轉換爲RGB並將顏色過濾器應用於其中。Android中換入紅色和藍色
的代碼非常簡單,在傳遞給該功能的過濾器出現問題:
public native void decode(Bitmap target, byte[] source, int filter);
目標是一個ImageView的基準
源是幀預覽數據
濾波器是濾色器
當碼是這樣的:
decode(mImageRed, data, 0xFFFF0000);
decode(mImageGreen, data, 0xFF00FF00);
decode(mImageBlue, data, 0xFF0000FF);
位圖以紅色和藍色交換顯示,沒有綠色問題。
當我換了紅色和藍色濾色片是這樣的:
decode(mImageRed, data, 0xFF0000FF);
decode(mImageGreen, data, 0xFF00FF00);
decode(mImageBlue, data, 0xFFFF0000);
*改變0xFF0000FF濾波器0xFFFF0000地址爲紅色圖像,反之亦然。
在本地部分,它的作用是剛剛與位運算符和(&)應用過濾器:
bitmapContent[yIndex] &= pFilter;
有誰知道,而色彩交換?因爲我認爲0xFFFF0000是紅色的而不是0xFF0000FF。
這裏是解碼功能:
void JNICALL
decode(JNIEnv *pEnv, jclass pClass, jobject pTarget, jbyteArray pSource, jint pFilter) {
// Retrieves bitmap information and locks it for drawing.
AndroidBitmapInfo bitmapInfo;
uint32_t *bitmapContent;
if (AndroidBitmap_getInfo(pEnv, pTarget, &bitmapInfo) < 0)
abort();
if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
abort();
if (AndroidBitmap_lockPixels(pEnv, pTarget, (void **) &bitmapContent) < 0)
abort();
// Accesses source array data.
jbyte *source = (*pEnv)->GetPrimitiveArrayCritical(pEnv, pSource, 0);
if (source == NULL)
abort();
int32_t frameSize = bitmapInfo.width * bitmapInfo.height;
int32_t yIndex, uvIndex, x, y;
int32_t colorY, colorU, colorV;
int32_t colorR, colorG, colorB;
int32_t y1192;
// Processes each pixel and converts YUV to RGB color.
// Algorithm originates from the Ketai open source project.
// See http://ketai.googlecode.com/.
for (y = 0, yIndex = 0; y < bitmapInfo.height; y++) {
colorU = 0;
colorV = 0;
// Y is divided by 2 because UVs are subsampled vertically.
// This means that two consecutives iterations refer to the
// same UV line (e.g when Y=0 and Y=1).
uvIndex = frameSize + (y >> 1) * bitmapInfo.width;
for (x = 0; x < bitmapInfo.width; x++, yIndex++) {
// Retrieves YUV components. UVs are subsampled
// horizontally too, hence %2 (1 UV for 2 Y).
colorY = max(toInt(source[yIndex]) - 16, 0);
if (!(x % 2)) {
colorV = toInt(source[uvIndex++]) - 128;
colorU = toInt(source[uvIndex++]) - 128;
}
// Computes R, G and B from Y, U and V.
y1192 = 1192 * colorY;
colorR = (y1192 + 1634 * colorV);
colorG = (y1192 - 833 * colorV - 400 * colorU);
colorB = (y1192 + 2066 * colorU);
colorR = clamp(colorR, 0, 262143);
colorG = clamp(colorG, 0, 262143);
colorB = clamp(colorB, 0, 262143);
// Combines R, G, B and A into the final pixel color.
bitmapContent[yIndex] = color(colorR, colorG, colorB);
bitmapContent[yIndex] &= pFilter;
}
}
(*pEnv)->ReleasePrimitiveArrayCritical(pEnv, pSource, source, 0);
if (AndroidBitmap_unlockPixels(pEnv, pTarget) < 0)
abort();
}
這裏如何位圖被分配:
mImageR = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mImageG = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mImageB = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
mImageViewR.setImageBitmap(mImageR);
mImageViewG.setImageBitmap(mImageG);
mImageViewB.setImageBitmap(mImageB);
確保錯誤不在於您顯示這些圖像的代碼中,否則,這部分代碼對我來說看起來很好。 – ZeekHuge
你是否使用過OpenCV(因爲它默認使用BGR)? – AKarthik10
我編輯了問題以發佈de本機代碼。 – PedroNakano