Android图像数据传递到C++的一些坑
最近在做一个Android图象识别的app, 通过相机预览或者是拍照功能获取图像数据,然后将图像数据传递到本地C++的图像识别so库。在这个过程中花的时间最多的就是数据传输问题。谨以此坑,警示未来!
首先,需要注意的几点:
1. android相机预览模式的回调函数的byte [] data参数,数据是YUV数据
首先,需要注意的几点:
1. android相机预览模式的回调函数的byte [] data参数,数据是YUV数据
2. android相机拍照模式的回调函数的byte [] data参数,数据是ARGB8888
3. java保存图像数据的数据byte[] 与C++中的unsigned char数据范围不一致,java byte: -128~127, C++ unsigned char: 0~255。
我的应用需求是:1. 拍照模式调用C++识别库
2. 底层C++的算法需要YUV格式的图像数据
所以,需要将拍照模式获取的图像数据ARGB8888转换到YUV。
![图片](http://a3.qpic.cn/psb?/V13m5mGH4D2vng/zecb.EJiyF.vAhid7OmKJ5J9bH.r9oTNiSRtyYbQBj0!/b/dOIAAAAAAAAA&ek=1&kp=1&pt=0&bo=WwI4AlsCOAIBEDc!&t=5&su=0256803969&tm=1517817600&sce=0-12-12&rf=2-9)
而在上面代码中,将byte数据强制转换到int,超过127的数据都会减掉256,即:
if (a > 127)
{
a -= 256;
}
接着将rgb的byte数组转换到yuv数组:
![图片](http://a1.qpic.cn/psb?/V13m5mGH4D2vng/h64.LaatcNYiOPY.79XNJgKl8eaO3nQz0VuzWKNAUic!/b/dPQAAAAAAAAA&ek=1&kp=1&pt=0&bo=qwKAAlEDHAMBEFE!&t=5&su=0154155617&tm=1517817600&sce=0-12-12&rf=2-9)
由于这里的RGB转YUV的的公式是针对RGB数值范围在(0~255)的,所以必须先将之前RGB的数值范围在-128~127的范围转回到(0~255),此时就是小于零的数据加上256就行了
![图片](http://a1.qpic.cn/psb?/V13m5mGH4D2vng/UKSo0sBCzhbpbs3tu*2weIlWuswMyJ2haKV1a.0g6II!/b/dPQAAAAAAAAA&ek=1&kp=1&pt=0&bo=fwFWAH8BVgABEDc!&t=5&su=082032945&tm=1517817600&sce=0-12-12&rf=2-9)
这样转换出来的YUV也在0~255之间,然后在强制类型转换成byte, 最后yuv的数据就是byte数据,范围-128~127,将这样的YUV直接给jni接口传递到算法内部即可。
注意jni的算法接口也是byte []. YUV(-128~127)的数据传给jni接口,算法内部(C++)会自动解析到本地的unsigned char范围(0~255)。
PS: 其实可以从bitmap的数据中直接保存RGB为int数组,然后不用再转化数据类型,用YUV的公式转换到yuv,最后将int的yuv强制转换到byte数组就行.
3. java保存图像数据的数据byte[] 与C++中的unsigned char数据范围不一致,java byte: -128~127, C++ unsigned char: 0~255。
我的应用需求是:1. 拍照模式调用C++识别库
2. 底层C++的算法需要YUV格式的图像数据
所以,需要将拍照模式获取的图像数据ARGB8888转换到YUV。
而在上面代码中,将byte数据强制转换到int,超过127的数据都会减掉256,即:
if (a > 127)
{
a -= 256;
}
接着将rgb的byte数组转换到yuv数组:
由于这里的RGB转YUV的的公式是针对RGB数值范围在(0~255)的,所以必须先将之前RGB的数值范围在-128~127的范围转回到(0~255),此时就是小于零的数据加上256就行了
这样转换出来的YUV也在0~255之间,然后在强制类型转换成byte, 最后yuv的数据就是byte数据,范围-128~127,将这样的YUV直接给jni接口传递到算法内部即可。
注意jni的算法接口也是byte []. YUV(-128~127)的数据传给jni接口,算法内部(C++)会自动解析到本地的unsigned char范围(0~255)。
PS: 其实可以从bitmap的数据中直接保存RGB为int数组,然后不用再转化数据类型,用YUV的公式转换到yuv,最后将int的yuv强制转换到byte数组就行.
版权所有,违者必究
(欢迎转载与交流 (wujianping.2006@163.com), 转载必须注明出处)
(欢迎转载,但必须注明出处。欢迎大家交流:wujianping.2006@163.com)