最近在搞视频分析类的项目,android默认视频采集格式是NV21,Y Cr Cb格式,4.2.0.方式采样 还有其他采样方式,默认使用NV21

Sets the image format for preview pictures.

If this is never called, the default format will beNV21, which uses the NV21 encoding format.

int JPEG Encoded formats.
int NV16 YCbCr format, used for video.
int NV21 YCrCb format used for images, which uses the NV21 encoding format.
int RGB_565 RGB format used for pictures encoded as RGB_565 seesetPictureFormat(int).
int UNKNOWN
int YUY2 YCbCr format used for images, which uses YUYV (YUY2) encoding format.
int YV12 Android YUV format: This format is exposed to software decoders and applications.
具体参见 http://developer.android.com/reference/android/graphics/ImageFormat.html ----------------------------------------------------------------------------------------------------------- 首先是其数据是怎样存储的 // 我们通过下列方式获取数据 class Buf implements Camera.PreviewCallback { public byte[] yuv420sp =null; public void onPreviewFrame(byte[] data, Camera camera) { // 这里出来的data和tackPic出来的有区别,这边是NV21格式 yuv420sp=data; } } 420这种格式采样方式如下 X X X X O O X X X X
X X X X O O X X X X 即每4个Y对应一个U和一个V Y0U0V0 Y1 Y2U2V2 Y3 Y4 Y5 Y6 Y7 Y8U8V8 Y9 Y10U10V10 Y11 Y12 Y13 Y14 Y15 通过对采样数组的研究其存放规律是 YYYYY...(采样宽度width)...YYYYY ... ...(采样高度height) ... YYYYY...(采样宽度width)...YYYYY (vu)(vu)(vu)...(采样宽度)...(vu)(vu)(vu) ...(采样高度除以2,height/2,遇单加1) (vu)(vu)(vu)...(采样宽度)...(vu)(vu)(vu) 即width=320,height=480,采样Y值长度320×480,采样VU长度320×480/2.yuv420sp=data;总长度为宽高乘积的一点五倍
// YUV转RGB rgb长度即width×heght static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); } } }
以上是android自带的YUV420SP转RGB的函数,但是坑爹的问题在于函数处理数据的能力有限,我们有的时候并不需要全部转完毕再解析。 以下是更改后的方法,用于取值某点的RGB,在一些实时性要求的应用中可以用到 // 自定义RGB static public int myDecodeYUV420SP(byte[] yuv420sp, int width, int height, int mWidth, int mHeight) { // Y矩阵长度frameSize , V和U矩阵第一位即frameSize final int frameSize = width * height; // yp为Y在矩阵中的位置,yph为所需要点的高mHeight-1,ypw为所需要点的宽mWidth int yp, yph = mHeight - 1, ypw = mWidth; yp = width * yph + ypw; // uvp为 // uv在数组中的位置,V和U矩阵第一位即frameSize,yph>>1取值范围(0,0,1,1,2,2...)yph从0开始,即UV数组为Y数组的1/2. int uvp = frameSize + (yph >> 1) * width, u = 0, v = 0; // 获取Y的数值 int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((ypw & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp]) - 128; } else { u = (0xff & yuv420sp[uvp--]) - 128; v = (0xff & yuv420sp[uvp]) - 128; }
int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143;
return (0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff));
}
两套函数出来的数据int型需要转换成r/g/b。亮点就是转换方式

public static intred(int color)

Since: API Level 1

Return the red component of a color int. This is the same as saying(color >> 16) & 0xFF

public static intgreen(int color)

Since: API Level 1

Return the green component of a color int. This is the same as saying(color >> 8) & 0xFF

public static intblue(int color)

Since: API Level 1

Return the blue component of a color int. This is the same as sayingcolor & 0xFF

至此yuv取点rgb完成 1 需要代码的童鞋可以留下你的email 2 如果描述有误请指正 3 感谢 幸福的起点 博主,更多视频格式说明请参照 http://hi.baidu.com/joygogo0130/blog/item/04b707529efbec090df3e345.html 4 更多视频问题 请参照 http://developer.android.com/reference/android/graphics/Camera.html http://ai4work.blog.163.com/blog/static/189873306201171883316264/

更多相关文章

  1. Android(安卓)UI学习 - GridView和ImageView的使用
  2. Android实现圆角矩形和圆形ImageView的方式
  3. android 里 meta-data 的使用
  4. Android(安卓)创建与解析XML(二)—— Dom方式
  5. Android(安卓)OpenGL射线拾取&手势旋转(二)
  6. ConstraintLayout 实现水平方向 权重 效果
  7. Android如何设置圆角按钮 类似微信的登陆按钮
  8. android4.4 Launcher主菜单界面同样采用背景图片的方式
  9. Android实现ImageView图片双击放大及缩小

随机推荐

  1. android skia decode returned false
  2. [CSDN]Android系统进程Zygote启动过程的
  3. android gps杂乱分析
  4. Android有用代码片段(二)
  5. Android使用SQLite数据库(2)
  6. android中Media Playback(媒体播放)
  7. Material Design设计规范
  8. android加载文件的方式,路径的写法
  9. android中创建目录以及txt文件
  10. android代码编写布局和控件