个人觉得libyuv性能更好,建议使用libyuv,地址:https://www.raoyunsoft.com/wordpress/index.php/2020/05/25/androidlibyuv/

史上最强的YUV转换RenderScript,支持转换成RGBA,BGRA,并且同时支持旋转,翻转,YUV数据格式支持NV21, YV12, YUV420_888, 分别对应Android Camera1API 以及Camera2 API 的YUV处理

​ 这段时间在做一些Android Camera数据处理的相关工作,涉及到YUV转RGBA的事情,由于对性能要求极高我先后采用了多种方案,最开始的时候是试用OpenCV里面的方法,最后发现性能不是很理想,最后又使用了libyuv,这个库性能要比OpenCV要好,对性能要求不是特别高的可以采用,这个库有一定的缺陷,YUV转换后图像还原度很不好,明显感觉到有色差,而且在Android手机上长时间运行,性能下降明显,最后没有办法了开始采用RenderScript,这里不得不吐槽一下Google 他仅仅提供了一个ScriptIntrinsicYuvToRGB,而且不支持YUV420_888,也不支持旋转,翻转,我呸渣男! 还能怎么办自己动手吧!

话不多说直接上代码吧(里面涉及到很多YUV的知识我就不讲了):

#pragma version(1)
#pragma rs java_package_name(com.luoye.bzyuv)
#pragma rs_fp_relaxedrs_allocation mInput;rs_allocation mInY;
rs_allocation mInU;
rs_allocation mInV;
rs_allocation mInNV21;
rs_allocation mInYV12;
int inWidth=0,inHeight=0;
int orientation=0;
bool flipY=false;
int uvPixelStride=1;static uchar4 yuvToRGBA4(uchar y, uchar u, uchar v) {short Y = ((short)y) - 16;short U = ((short)u) - 128;short V = ((short)v) - 128;short4 p;p.x = (Y * 298 + V * 409 + 128) >> 8;p.y = (Y * 298 - U * 100 - V * 208 + 128) >> 8;p.z = (Y * 298 + U * 516 + 128) >> 8;p.w = 255;if(p.x < 0) {p.x = 0;}if(p.x > 255) {p.x = 255;}if(p.y < 0) {p.y = 0;}if(p.y > 255) {p.y = 255;}if(p.z < 0) {p.z = 0;}if(p.z > 255) {p.z = 255;}return (uchar4){p.x, p.y, p.z, p.w};
}static float4 yuvToRGBA_f4(uchar y, uchar u, uchar v) {float4 yuv_U_values = {0.f, -0.392f * 0.003921569f, +2.02 * 0.003921569f, 0.f};float4 yuv_V_values = {1.603f * 0.003921569f, -0.815f * 0.003921569f, 0.f, 0.f};float4 color = (float)y * 0.003921569f;float4 fU = ((float)u) - 128.f;float4 fV = ((float)v) - 128.f;color += fU * yuv_U_values;color += fV * yuv_V_values;color = clamp(color, 0.f, 1.f);return color;
}void makeRef(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {uint32_t w = rsAllocationGetDimX(ay);uint32_t h = rsAllocationGetDimY(ay);for (int y = 0; y < h; y++) {//rsDebug("y", y);for (int x = 0; x < w; x++) {int py = rsGetElementAt_uchar(ay, x, y);int pu = rsGetElementAt_uchar(au, x >> 1, y >> 1);int pv = rsGetElementAt_uchar(av, x >> 1, y >> 1);//rsDebug("py", py);//rsDebug(" u", pu);//rsDebug(" v", pv);uchar4 rgb = yuvToRGBA4(py, pu, pv);//rsDebug("  ", rgb);rsSetElementAt_uchar4(aout, rgb, x, y);}}
}void makeRef_f4(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {uint32_t w = rsAllocationGetDimX(ay);uint32_t h = rsAllocationGetDimY(ay);for (int y = 0; y < h; y++) {//rsDebug("y", y);for (int x = 0; x < w; x++) {uchar py = rsGetElementAt_uchar(ay, x, y);uchar pu = rsGetElementAt_uchar(au, x >> 1, y >> 1);uchar pv = rsGetElementAt_uchar(av, x >> 1, y >> 1);//rsDebug("py", py);//rsDebug(" u", pu);//rsDebug(" v", pv);float4 rgb = yuvToRGBA_f4(py, pu, pv);//rsDebug("  ", rgb);rsSetElementAt_float4(aout, rgb, x, y);}}
}static void setLocation(int x,int y, int*targetX,int *targetY){int finalX=x;int finalY=y;if(orientation!=0){if(orientation==90){finalX=y;finalY=inHeight-1-x;if(flipY){finalX=inWidth-1-finalX;}}else if(orientation==180){finalX=inWidth - 1 - x;finalY=inHeight - 1 - y;if(flipY){finalY=inHeight-1-finalY;}}else if(orientation==270){finalX=inWidth - 1 - y;finalY=x;if(flipY){finalY=inHeight-1-finalY;}}}else{if(flipY){finalY=inHeight-1-finalY;}}*targetX=finalX;*targetY=finalY;
}uchar4 __attribute__((kernel)) yuv_420_888_2_rgba(uint32_t x, uint32_t y) {if(inWidth<=0||inHeight<=0){rsDebug("bz_inWidth<=0||inHeight<=0", inWidth,inHeight);return '0';}int targetX=x;int targetY=y;setLocation(x,y,&targetX,&targetY);uint uvIndex= uvPixelStride*(targetX/2)+ uvPixelStride*(inWidth/2)*(targetY/2);uchar yps= rsGetElementAt_uchar(mInY,targetX,targetY);uchar u= rsGetElementAt_uchar(mInU,uvIndex);uchar v= rsGetElementAt_uchar(mInV,uvIndex);return yuvToRGBA4(yps, u, v);
}uchar4 __attribute__((kernel)) yuv_420_888_2_bgra(uint32_t x, uint32_t y) {if(inWidth<=0||inHeight<=0){rsDebug("bz_inWidth<=0||inHeight<=0", inWidth,inHeight);return '0';}int targetX=x;int targetY=y;setLocation(x,y,&targetX,&targetY);uint uvIndex= uvPixelStride*(targetX/2)+ uvPixelStride*(inWidth/2)*(targetY/2);uchar yps= rsGetElementAt_uchar(mInY,targetX,targetY);uchar u= rsGetElementAt_uchar(mInU,uvIndex);uchar v= rsGetElementAt_uchar(mInV,uvIndex);uchar4 rgba= yuvToRGBA4(yps, u, v);return (uchar4){rgba.z, rgba.y, rgba.x,rgba.w};
}uchar4 __attribute__((kernel)) yuv_yv12_2_rgba(uint32_t x, uint32_t y) {if(inWidth<=0||inHeight<=0){rsDebug("bz_inWidth<=0||inHeight<=0", inWidth,inHeight);return '0';}int targetX=x;int targetY=y;setLocation(x,y,&targetX,&targetY);uint yIndex=targetX+inWidth*targetY;uint uIndex=inWidth*inHeight+ (targetX/2) + inWidth/2*(targetY/2);uint vIndex=inWidth*inHeight+inWidth*inHeight/4+ (targetX/2) + inWidth/2*(targetY/2);uchar yps= rsGetElementAt_uchar(mInYV12,yIndex);uchar u= rsGetElementAt_uchar(mInYV12,uIndex);uchar v= rsGetElementAt_uchar(mInYV12,vIndex);return yuvToRGBA4(yps, v, u);
}uchar4 __attribute__((kernel)) yuv_yv12_2_bgra(uint32_t x, uint32_t y) {if(inWidth<=0||inHeight<=0){rsDebug("bz_inWidth<=0||inHeight<=0", inWidth,inHeight);return '0';}int targetX=x;int targetY=y;setLocation(x,y,&targetX,&targetY);uint yIndex=targetX+inWidth*targetY;uint uIndex=inWidth*inHeight+ (targetX/2) + inWidth/2*(targetY/2);uint vIndex=inWidth*inHeight+inWidth*inHeight/4+ (targetX/2) + inWidth/2*(targetY/2);uchar yps= rsGetElementAt_uchar(mInYV12,yIndex);uchar u= rsGetElementAt_uchar(mInYV12,uIndex);uchar v= rsGetElementAt_uchar(mInYV12,vIndex);uchar4 rgba= yuvToRGBA4(yps, v, u);return (uchar4){rgba.z, rgba.y, rgba.x,rgba.w};
}uchar4 __attribute__((kernel)) yuv_nv21_2_rgba(uint32_t x, uint32_t y) {if(inWidth<=0||inHeight<=0){rsDebug("bz_inWidth<=0||inHeight<=0", inWidth,inHeight);return '0';}int targetX=x;int targetY=y;setLocation(x,y,&targetX,&targetY);uint yIndex=targetX+inWidth*targetY;uint uIndex=inWidth*inHeight+ 2*(targetX/2) + inWidth*(targetY/2);uint vIndex=inWidth*inHeight+ 2*(targetX/2) + inWidth*(targetY/2)+1;uchar yps= rsGetElementAt_uchar(mInNV21,yIndex);uchar u= rsGetElementAt_uchar(mInNV21,uIndex);uchar v= rsGetElementAt_uchar(mInNV21,vIndex);return yuvToRGBA4(yps, v, u);
}uchar4 __attribute__((kernel)) yuv_nv21_2_bgra(uint32_t x, uint32_t y) {if(inWidth<=0||inHeight<=0){rsDebug("bz_inWidth<=0||inHeight<=0", inWidth,inHeight);return '0';}int targetX=x;int targetY=y;setLocation(x,y,&targetX,&targetY);uint yIndex=targetX+inWidth*targetY;uint uIndex=inWidth*inHeight+ 2*(targetX/2) + inWidth*(targetY/2);uint vIndex=inWidth*inHeight+ 2*(targetX/2) + inWidth*(targetY/2)+1;uchar yps= rsGetElementAt_uchar(mInNV21,yIndex);uchar u= rsGetElementAt_uchar(mInNV21,uIndex);uchar v= rsGetElementAt_uchar(mInNV21,vIndex);uchar4 rgba= yuvToRGBA4(yps, v, u);return (uchar4){rgba.z, rgba.y, rgba.x,rgba.w};
}float4 __attribute__((kernel)) cvt_f4(uint32_t x, uint32_t y) {uchar py = rsGetElementAtYuv_uchar_Y(mInput, x, y);uchar pu = rsGetElementAtYuv_uchar_U(mInput, x, y);uchar pv = rsGetElementAtYuv_uchar_V(mInput, x, y);//rsDebug("py2", py);//rsDebug(" u2", pu);//rsDebug(" v2", pv);return rsYuvToRGBA_float4(py, pu, pv);
}

The supported methods are as follows:

  1. yuv_yv12_2_Bitmap
  2. yuv_yv12_2_RGBA
  3. yuv_yv12_2_BGRA
  4. yuv_nv21_2_Bitmap
  5. yuv_nv21_2_RGBA
  6. yuv_nv21_2_BGRA
  7. yuv420_2_Bitmap
  8. yuv420_2_RGBA
  9. yuv420_2_BGRA

原文与Demo地址:http://www.raoyunsoft.com/wordpress/index.php/2020/01/19/yuvrenderscript/

史上最强的YUV转换RenderScript,支持转换成RGBA,BGRA,并且同时支持旋转,翻转,YUV数据格式支持NV21, YV12, YUV420_888, 分别对应Android Camer相关推荐

  1. 【CV中的注意力机制】史上最强ResNet变体--ResNeSt

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! [前言]:我们前面已经详细介绍了Attention机制和视觉注意力机制在图像分类结 ...

  2. 史上最强GAN:训练费10万起,现在免费体验,画风鬼畜又逼真

    夏乙 郭一璞 安妮 晓查 发自 亚龙湾  量子位 报道 | 公众号 QbitAI ?好消息!好消息! 9月底轰动业界的史上最强GAN,也就是最高动用512个TPU训练的BigGAN,Demo已经正式放 ...

  3. 史上最强Vue,面试、项目全靠它

    史上最强Vue,面试.项目全靠它 vue框架篇 vue的优点 数据驱动的理解 MVVM的理解 组件化的理解 1.组件定义 2.组件的使用场景 3.如何使用组件 4.vue组件产生的过程 数据闪烁 请详 ...

  4. 史上最强网页工具集合-MikuTools

    史上最强网页工具集合 媒体类 其他工具 图片相关 文字处理 编程开发 网站设置 今天给大家推荐一个网页版工具集合 MikuTools,从视频下载到图片处理再到编程开发,简直就是无所不能. 该工具里面大 ...

  5. 史上最强女游戏程序员

    也许你听说过John Carmack 和Tim Sweeney等大牛的名字,而向来游戏工业都是阳盛阴衰,适逢国际妇女节,今天我为大家介绍游戏业界一位史上最强女游戏程序员:Corrinne Yu. 简历 ...

  6. “史上最强”BigGAN公开TensorFlow Hub demo!

    还记得前些日子轰动一时的 BigGAN 模型吗?生成对抗网络(GAN)作为当前最热门的技术之一,最近在图像生成方面的成果颇受人关注.近日,由 DeepMind 和赫瑞瓦特大学组成的科研人员公布的 Bi ...

  7. 英伟达发布史上最强GPU,却叫停了自动驾驶车路测

    作者 | DavidZh 出品 | AI科技大本营(公众号ID:rgznai100) 当地时间 3 月 27 日,英伟达在美国圣克拉的 GTC 大会上推出多款产品. ▌显卡扩容,史上最强的 DGX-2 ...

  8. 【经典干货】GitHub标星10万+,史上最强Google面试指南!

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 一位从1997年就入行的Web工程师,立志要成为Google软件工程师,3年前写下 ...

  9. 【学术前沿】26 亿参数训练量,水平接近人类,Google 开发的“史上最强”聊天机器人意义何在?...

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 来源:雷锋网 科技巨头们时不时就声明在 AI 领域取得了突破性进展,对此我们已经见 ...

最新文章

  1. jquery中ajax参数说明
  2. 云栖大会特享,热营抢先开,阿里云专家的私教课,限时抢报!
  3. MySQL数据库时区问题导致java程序无法连接数据库
  4. jenkins没安装git报错
  5. admin select 2 异步_解决Angularjs异步操作后台请求用$q.all排列先后顺序问题
  6. SAP License:SAP中的一些问题及处理
  7. python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告(二)
  8. 《昆虫记》思维导图|思维导图模板创意漂亮
  9. 备份Ubuntu 并制作成iso安装文件
  10. 用以促学——Linux进程后台运行的原理、方法、比较及其实现
  11. 电脑显示请检查映像服务器,该任务映像已损坏或已篡改的解决方法
  12. 2022年4月13日记
  13. flash 在firebox/IE中 提示安装 浏览器是否有flash插件
  14. 如何在网页版163邮箱中添加别的邮箱
  15. 锐捷网络:校园网基于802.1x无感知认证
  16. OpenSSL ssL_read: Connection was aborted,errno 10053 报错
  17. 《React极简教程》第一章 Hello,World!
  18. FPGA图像处理HLS实现sobel边沿检测,提供HLS工程和vivado工程源码
  19. RocketMQ——Mac电脑OS系统docker安装Dashboard
  20. 微CLI工具箱-WeToolkit

热门文章

  1. 更灵敏、更精准、更智能,机器人避障也能“随心所欲”
  2. matlab 画随机数图,怎么用matlab生成100个标准正态分布的随机数并画出直方图
  3. Java入门云计算:从基础到实践
  4. Java NIO示例
  5. 基于ADS的简单射频电路调试
  6. 如何用MATLAB检测一张图片中某种颜色的占比
  7. MATLAB 拉格朗日方程 求三自由度机械
  8. Cucumber Rerun Formatter
  9. tendermint 六:默克尔树
  10. 如何去除百度地图下方的文字标识