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); 
 } 

    大家可以自行优化呵呵!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android 中,使用 Camera API 获取的图像数据通常是以 YUV 格式传输的。要将 YUV 数据转换为 RGB,可以使用以下方法: 1. 使用 Android 提供的 YUV 转换工具类:YuvImage 和 BitmapFactory。这种方法的缺点是比较耗时,而且需要将 YUV 数据先转换为 JPEG 或 PNG 格式,然后再转换为 RGB。代码示例: ``` YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null); ByteArrayOutputStream out = new ByteArrayOutputStream(); yuvImage.compressToJpeg(new Rect(0, 0, width, height), 50, out); byte[] imageBytes = out.toByteArray(); Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); ``` 2. 使用 RenderScript 进行 YUV 转换。RenderScript 是 Android 提供的高性能计算引擎,可以在 GPU 上进行并行计算,比 CPU 要快很多。代码示例: ``` RenderScript rs = RenderScript.create(context); ScriptIntrinsicYuvToRGB yuvToRgb = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length); Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); in.copyFrom(data); Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height); Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); yuvToRgb.setInput(in); yuvToRgb.forEach(out); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); out.copyTo(bitmap); rs.destroy(); ``` 注意:以上代码示例中的参数 data 是 byte[] 类型的 YUV 数据,width 和 height 分别是图像宽度和高度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Trent1985

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

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

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

打赏作者

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

抵扣说明:

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

余额充值