Open a284628487 opened 6 years ago
Java代码:
public static native void YUVtoARGB(byte[] yuv, int width, int height, int[] out);
C代码:
#include <jni.h> #include <android/log.h> JNIEXPORT void JNICALL Java_com_ccflying_JNIBitmap_YUVtoARGB(JNIEnv *env, jobject obj, jbyteArray yuv420sp, jint width, jint height, jintArray rgbOut) { // byte[] yuv, int width, int height, int[] out int sz; int i; int j; int Y; int U = 0; int V = 0; int pixPtr = 0; int jDiv2 = 0; int R = 0; int G = 0; int B = 0; int cOff; // int w = width; int h = height; // 总像素点个数 sz = w * h; // 输出结果: pixels jint *rgbData = (jint *) ((*env)->GetPrimitiveArrayCritical(env, rgbOut, 0)); // Camera原始byte数据 jbyte *yuv = (jbyte *) (*env)->GetPrimitiveArrayCritical(env, yuv420sp, 0); for (j = 0; j < h; j++) { // height: 从上到下 pixPtr = j * w; // 第 j 行左侧位置索引 jDiv2 = j >> 1; // jDiv2为j整除2 for (i = 0; i < w; i++) { // width: 从左到右 Y = yuv[pixPtr]; // Y 行第 i 个像素点 if (Y < 0) Y += 255; // ? (i & 0x1) 表示 i 为单数(奇数),1, 3, 5, 7, 9 if ((i & 0x1) != 1) { cOff = sz + jDiv2 * w + (i >> 1) * 2; U = yuv[cOff]; // U V = yuv[cOff + 1]; // V if (U < 0) U += 127; else U -= 128; if (V < 0) V += 127; else V -= 128; } // 使用的是 comment#2 中的4:2:2采样格式 //ITU-R BT.601 conversion // //R = 1.164*(Y-16) + 2.018*(U-128); //G = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128); //B = 1.164*(Y-16) + 1.596*(V-128); // Y = Y + (Y >> 3) + (Y >> 5) + (Y >> 7); // R R = Y + (int)(1.4f * U); R = limitRGBValue(R); // G G = Y - (int)(0.344f * V + 0.714f * U); G = limitRGBValue(G); // B B = Y + (int)(1.77f * V); B = limitRGBValue(B); // 写入进结果 pixels rgbData[pixPtr++] = 0xff000000 + (R << 16) + (G << 8) + B; // ARBG? // rgbData[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; } } // release (*env)->ReleasePrimitiveArrayCritical(env, rgbOut, rgbData, 0); (*env)->ReleasePrimitiveArrayCritical(env, yuv420sp, yuv, 0); } // 限制RGB值的范围为[0-255] int limitRGBValue(int input) { if (input < 0) input = 0; else if (input > 255) input = 255; return input; }
Link
YUVtoARGB
Java代码:
C代码:
Link