Ein Beispiel von Sylvain Ratabouil Android NDK (2nd Edition), die Bildvorschauen von der Kamera erhält und nativ verarbeitet, von YUV zu RGB konvertiert und einen Farbfilter darauf anwendet.Rote und blaue Farben werden in Android
Der Code ist sehr einfach und das Problem tritt in den Filter, die diese Funktion übergeben wird:
public native void decode(Bitmap target, byte[] source, int filter);
Ziel ist ein Verweis auf eine Image
Quelle ist die Rahmenvorschaudaten
Filter sind der Farbfilter
Wenn der Code wie folgt lautet:
decode(mImageRed, data, 0xFFFF0000);
decode(mImageGreen, data, 0xFF00FF00);
decode(mImageBlue, data, 0xFF0000FF);
Die Bitmaps werden mit roten und blauen Farben angezeigt, kein Problem mit Grün.
Wenn ich die roten und blauen Farbfiltern wie folgt auszutauschen:
decode(mImageRed, data, 0xFF0000FF);
decode(mImageGreen, data, 0xFF00FF00);
decode(mImageBlue, data, 0xFFFF0000);
* Ändern 0xFF0000FF Filter mit 0xFFFF0000 für das rote Bild und umgekehrt.
Im nativen Teil, was es die Filter hat sie gilt nur mit dem Bit-Operator und (&):
bitmapContent[yIndex] &= pFilter;
niemand kennt, während die Farben vertauscht? Weil ich dachte, dass 0xFFFF0000 rot war und nicht 0xFF0000FF. Hier
ist die Dekodierungsfunktion:
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();
}
Und hier, wie die Bitmaps zugeordnet sind:
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);
Stellen Sie sicher, dass der Fehler nicht in dem Code liegt, in dem Sie diese Bilder anzeigen, sonst sieht dieser Teil des Codes gut für mich aus. – ZeekHuge
Verwenden Sie OpenCV zufällig (wie es BGR standardmäßig verwendet)? – AKarthik10
Ich habe die Frage editiert, um de nativen Code zu posten. – PedroNakano