Android--YUV-RGB

    最近在网上看到一个android中实现YUV与RGB互相转换的代码,效率还行,特给大家分享一下,这段代码是在JNI 层编写的,主要用在Camera视频流开发中实时处理YUV数据的情况,比如图像处理中的一些实时滤镜,需要把Camera得到的YUV数据转为RGB数据进行处理,然后再转换为YUV数据来显示。

    具体代码如下:

   

#include <jni.h> 
#include <android/log.h> 
  
  
 JNIEXPORT void JNICALL Java_jp_co_cyberagent_android_gpuimage_GPUImageNativeLibrary_YUVtoRBGA(JNIEnv * env, jobject obj, jbyteArray yuv420sp, jint width, jint height, jintArray rgbOut) 
 { 
 int sz; 
 int i; 
 int j; 
 int Y; 
 int Cr = 0; 
 int Cb = 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; 
  
 jint *rgbData = (jint*) ((*env)->GetPrimitiveArrayCritical(env, rgbOut, 0)); 
 jbyte* yuv = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, yuv420sp, 0); 
  
 for(j = 0; j < h; j++) { 
 pixPtr = j * w; 
 jDiv2 = j >> 1; 
 for(i = 0; i < w; i++) { 
 Y = yuv[pixPtr]; 
 if(Y < 0) Y += 255; 
 if((i & 0x1) != 1) { 
 cOff = sz + jDiv2 * w + (i >> 1) * 2; 
 Cb = yuv[cOff]; 
 if(Cb < 0) Cb += 127; else Cb -= 128; 
 Cr = yuv[cOff + 1]; 
 if(Cr < 0) Cr += 127; else Cr -= 128; 
 } 
 R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); 
 if(R < 0) R = 0; else if(R > 255) R = 255; 
 G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); 
 if(G < 0) G = 0; else if(G > 255) G = 255; 
 B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); 
 if(B < 0) B = 0; else if(B > 255) B = 255; 
 rgbData[pixPtr++] = 0xff000000 + (R << 16) + (G << 8) + B; 
 } 
 } 
  
 (*env)->ReleasePrimitiveArrayCritical(env, rgbOut, rgbData, 0); 
 (*env)->ReleasePrimitiveArrayCritical(env, yuv420sp, yuv, 0); 
 } 
  
 JNIEXPORT void JNICALL Java_jp_co_cyberagent_android_gpuimage_GPUImageNativeLibrary_YUVtoARBG(JNIEnv * env, jobject obj, jbyteArray yuv420sp, jint width, jint height, jintArray rgbOut) 
 { 
 int sz; 
 int i; 
 int j; 
 int Y; 
 int Cr = 0; 
 int Cb = 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; 
  
 jint *rgbData = (jint*) ((*env)->GetPrimitiveArrayCritical(env, rgbOut, 0)); 
 jbyte* yuv = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, yuv420sp, 0); 
  
 for(j = 0; j < h; j++) { 
 pixPtr = j * w; 
 jDiv2 = j >> 1; 
 for(i = 0; i < w; i++) { 
 Y = yuv[pixPtr]; 
 if(Y < 0) Y += 255; 
 if((i & 0x1) != 1) { 
 cOff = sz + jDiv2 * w + (i >> 1) * 2; 
 Cb = yuv[cOff]; 
 if(Cb < 0) Cb += 127; else Cb -= 128; 
 Cr = yuv[cOff + 1]; 
 if(Cr < 0) Cr += 127; else Cr -= 128; 
 } 
 R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); 
 if(R < 0) R = 0; else if(R > 255) R = 255; 
 G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); 
 if(G < 0) G = 0; else if(G > 255) G = 255; 
 B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); 
 if(B < 0) B = 0; else if(B > 255) B = 255; 
 rgbData[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; 
 } 
 } 
  
 (*env)->ReleasePrimitiveArrayCritical(env, rgbOut, rgbData, 0); 
 (*env)->ReleasePrimitiveArrayCritical(env, yuv420sp, yuv, 0); 
 } 

    大家可以自行优化呵呵!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Trent1985

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值