我想将Android Camera采集的yuv420数据源直接纹理贴图,可是不知道怎么提取y、u、v分量,跪求解决啊、、、、androidCamera
解决方案 »
- in-app Billing 内置收费问题
- 求推荐几本java书籍
- AT 命令如何实现与RIL和底层的交互
- GridView怎么动态加载图标?求代码
- android 自动添加一个标签 并让此标签获得焦点
- 安卓应用闪退,求思路
- android sdk manager刷出来的可下载包对不上,咋整吖!?
- MotionEvent的getX()返回的数据单位是啥?像素?
- 怎么通过listview的item点击监听更新activity的其他控件
- android 5.1 root版本 修改framework相关内容后,模块编译出来的jar包push进系统后,修改部分不起作用。必须重新编译烧写system.
- 放大的动画如何设置参数?
- 请教个问题,如果apk中有4.0的API,安装在2.2的机器上的话
参考下下面的代码/**
* Converts YUV420 NV21 to ARGB8888
*
* @param data byte array on YUV420 NV21 format.
* @param width pixels width
* @param height pixels height
* @return a ARGB8888 pixels int array. Where each int is a pixels ARGB.
*/
public static int[] convertYUV420_NV21toARGB8888(byte [] data, int width, int height) {
int size = width*height;
int offset = size;
int[] pixels = new int[size];
int u, v, y1, y2, y3, y4;
// i along Y and the final pixels
// k along pixels U and V
for(int i=0, k=0; i < size; i+=2, k+=1) {
y1 = data[i ]&0xff;
y2 = data[i+1]&0xff;
y3 = data[width+i ]&0xff;
y4 = data[width+i+1]&0xff;
v = data[offset+k ]&0xff;
u = data[offset+k+1]&0xff;
v = v-128;
u = u-128;
pixels[i ] = convertYUVtoARGB(y1, u, v);
pixels[i+1] = convertYUVtoARGB(y2, u, v);
pixels[width+i ] = convertYUVtoARGB(y3, u, v);
pixels[width+i+1] = convertYUVtoARGB(y4, u, v);
if (i!=0 && (i+2)%width==0)
i+=width;
}
return pixels;
}
private static int convertYUVtoARGB(int y, int u, int v) {
int r,g,b;
r = y + (int)(1.402f*u);
g = y - (int)(0.344f*v + 0.714f*u);
b = y + (int)(1.772f*v);
r = r>255? 255 : r<0 ? 0 : r;
g = g>255? 255 : g<0 ? 0 : g;
b = b>255? 255 : b<0 ? 0 : b;
return 0xff000000 | (r<<16) | (g<<8) | b;
}
关于NV21的结构,可以参考下面的文章
http://ticktick.blog.51cto.com/823160/555791关于溢出的问题,我测试了一下,预览数据应该是没问题的,检查下是不是其他地方写错了Width: 480
Height: 640
size = Width * Height = 307200
data.length = 460800
data.length / size = 1.5
我觉得主要是Android Camera取出来的数据长度有问题,可能是压缩了或是怎么得。(数据结构这方面不太懂),我在java这边打印了的,不是1.5倍的长度而是1倍的长度。这是头疼的地方
你有看过Android Camera 获取的源数据的长度么?好像都是一陪的长度,和手机无关,好像~
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
Size size = camera.getParameters().getPreviewSize();
int format = camera.getParameters().getPreviewFormat();
}
10-12 12:06:31.916: D/@(29472): Data Length: 460800, Size: 640x480, format: 17
我试了下,然后我仿照你这个写了个在jni层的代码cpp的,用opengl纹理贴图之后颜色显示不出来,麻烦帮我看下,~~
JNIEXPORT void JNICALL Java_com_spore_CameraView_decodeframe(JNIEnv * pEnv,
jclass pClass, jbyteArray pSource, jint width, jint height,
jbyteArray ydata, jbyteArray udata, jbyteArray vdata) {
jbyte* data = (jbyte*) pEnv->GetByteArrayElements(pSource, 0);
int32_t size = width * height;
int32_t offset = size;
int32_t lFrameSize = width * height;
int32_t lYIndex, lUVIndex;
int32_t lM, lN;
int8_t lColorY[lFrameSize];
int8_t lColorU[lFrameSize / 4];
int8_t lColorV[lFrameSize / 4]; // i along Y and the final pixels
// k along pixels U and V
lM=0;
lN=0;
for (int i = 0, k = 0; i < size; i += 2, k += 1) {
lColorY[i] = data[i] & 0xff;
lColorY[i+1] = data[i + 1] & 0xff;
lColorY[width + i] = data[width + i] & 0xff;
lColorY[width + i + 1] = data[width + i + 1] & 0xff; lColorV[lN] = data[offset + k] & 0xff-128;
lColorU[lN] = data[offset + k + 1] & 0xff-128;
lN++; if (i != 0 && (i + 2) % width == 0)
i += width;
}
pEnv->SetByteArrayRegion(ydata, 0, lFrameSize, lColorY);
pEnv->SetByteArrayRegion(udata, 0, lFrameSize / 4, lColorU);
pEnv->SetByteArrayRegion(vdata, 0, lFrameSize / 4, lColorV); pEnv->ReleaseByteArrayElements(pSource, data, 0);}
大牛,能帮我看下么,我这边opengl贴图需要支持YV12的,所以我用了parameters.setPreviewFormat(ImageFormat.YV12);来设置预览格式
yuv提取用了for (int32_t i = 0, k = 0; i < size; i += 2, k += 1) {
lColorY[i] = data[i] ;
lColorY[i+1] = data[i + 1] ;
lColorY[width + i] = data[width + i] ;
lColorY[width + i + 1] = data[width + i + 1];
//
lColorV[lN] = data[offset + k];
lColorU[lN] = data[offset + k +width];
lN++; if (i != 0 && (i + 2) % width == 0)
i += width;
}但是会出现偏色
Android camera设置预览格式的时候,不一定什么格式都支持的,需要先检查一下android.hardware.Camera.Parameters.getSupportedPreviewFormats()另外吧,这个貌似你已经可以把RGB分量从YUV中解析出来了,
看你的截图,应该是把RGB分量组成Color值的时候某个分量写反了吧?在JNI里面读取/设置颜色的时候经常会有这种问题,你把R、G、B的值换换顺序?