以480640尺寸为例
Image对象获取到的RGBA_8888数据格式分析如下
1.getPixelStride方法获取相邻像素间距 = 4
2.getRowStride方法获取行跨度 = 2048
3.2048-4480 = 128,说明每行多出128个byte,这128个byte表示行填充的值,里面的数据为无效数据。
4.转换:需要将每行的最后128个数据忽略掉,再进行转换
JNIEXPORT void JNICALL
Java_com_xxx_xxx_RGBAtoNV21(JNIEnv *env,
jclass clazz,
jbyteArray rgbasp,
jint width,
jint height,
jint rowPadding,//行填充的值
jbyteArray yuvOut) {
jbyte *yuvData = (jbyte *) ((*env)->GetPrimitiveArrayCritical(env, yuvOut, 0));
jbyte *rgba = (jbyte *) ((*env)->GetPrimitiveArrayCritical(env, rgbasp, 0));
int length = (*env)->GetArrayLength(env, yuvOut);
int yIndex = 0;
int uvIndex = width * height;
int argbIndex = 0;
int R, G, B, Y, U, V;
for (int j = 0; j < height; ++j) {
for (int i = 0; i < width; ++i) {
R = rgba[argbIndex++] & 0xFF;
G = rgba[argbIndex++] & 0xFF;
B = rgba[argbIndex++] & 0xFF;
argbIndex++;//跳过a
Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
yuvData[yIndex++] = ((Y > 0xFF) ? 0xFF : ((Y < 0) ? 0 : Y));
//__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%hhd", yuvData[yIndex - 1]);
if ((j & 1) == 0 && ((argbIndex >> 2) & 1) == 0 && uvIndex < length - 2) {
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
yuvData[uvIndex++] = ((V > 0xFF) ? 0xFF : ((V < 0) ? 0 : V));
yuvData[uvIndex++] = ((U > 0xFF) ? 0xFF : ((U < 0) ? 0 : U));
}
}
argbIndex += rowPadding; //跳过rowPadding长度的填充数据
}
//__android_log_print(ANDROID_LOG_ERROR, LOG_TAG,"%s",s);
(*env)->ReleasePrimitiveArrayCritical(env, rgbasp, rgba, 0);
(*env)->ReleasePrimitiveArrayCritical(env, yuvOut, yuvData, 0);
}