android默认的视频采集格式是NV21,(属于YUV420)

在onPreviewFrame中传进来的byte[] data即为NV21格式。

旋转算法

对NV21进行顺时针旋转90度,180度和270度算法。

旋转90度

privatebyte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight){
byte[] yuv =newbyte[imageWidth*imageHeight*3/2];
// Rotate the Y luma
int i =0;
for(int x =0;x < imageWidth;x++){
for(int y = imageHeight-1;y >=0;y--){ 		            yuv[i]= data[y*imageWidth+x]; 		            i++;}   		    }
// Rotate the U and V color components  		    i = imageWidth*imageHeight*3/2-1;for(int x = imageWidth-1;x >0;x=x-2){for(int y =0;y < imageHeight/2;y++){ 		            yuv[i]= data[(imageWidth*imageHeight)+(y*imageWidth)+x]; 		            i--; 		            yuv[i]= data[(imageWidth*imageHeight)+(y*imageWidth)+(x-1)]; 		            i--;}}return yuv;}

用法:

//clockwise90:IplImage.create(480, 640) && new NewFFmpegFrameRecorder(480, 640)顺时针旋转90度, 将IplImage.create和new NewFFmpegFrameRecorder处源图像的宽高640x480对换成旋转后的真实宽高480x640 byte[] outdata;		 outdata = rotateYUV420Degree90(data, 640, 480); 

旋转180度

privatebyte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight){
byte[] yuv =newbyte[imageWidth*imageHeight*3/2];
int i =0;int count =0;   			for(i = imageWidth * imageHeight -1; i >=0; i--){ 				yuv[count]= data[i]; 				count++;}   			i = imageWidth * imageHeight *3/2-1;for(i = imageWidth * imageHeight *3/2-1; i >= imageWidth 					* imageHeight; i -=2){ 				yuv[count++]= data[i -1]; 				yuv[count++]= data[i];}return yuv;}

用法:

//clockwise180:IplImage.create(640, 480) && new NewFFmpegFrameRecorder(640, 480)上述2处无需改动 byte[] outdata;		 outdata = rotateYUV420Degree180(data, 640, 480); 

旋转270度

private byte[] rotateYUV420Degree270(byte[] data, int imageWidth, int imageHeight){
    byte[] yuv =new byte[imageWidth*imageHeight*3/2];
    // Rotate the Y luma
    int i =0;
    for(int x = imageWidth-1;x >=0;x--){
        for(int y =0;y < imageHeight;y++){
		            yuv[i]= data[y*imageWidth+x]; 		            i++;
        }   }// Rotate the U and V color components  	i = imageWidth*imageHeight;
    for(int x = imageWidth-1;x >0;x=x-2){
        for(int y =0;y < imageHeight/2;y++){ 		       yuv[i]= data[(imageWidth*imageHeight)+(y*imageWidth)+(x-1)]; 		         i++; 		       yuv[i]= data[(imageWidth*imageHeight)+(y*imageWidth)+x]; 		            i++;
        }
    }
    return yuv;
}

用法:

//clockwise270:IplImage.create(480, 640) && new NewFFmpegFrameRecorder(480, 640),设置与旋转90度相同 byte[] outdata;		 outdata = rotateYUV420Degree270(data, 640, 480); 

裁剪NV21

publicbyte[] cropYUV420(byte[] data,int imageW,int imageH,int newImageH){int cropH;int i,j,count,tmp;byte[] yuv =newbyte[imageW*newImageH*3/2];   		cropH =(imageH - newImageH)/2;   		count =0;for(j=cropH;j<cropH+newImageH;j++){for(i=0;i<imageW;i++){ 				yuv[count++]= data[j*imageW+i];}}   		//Cr Cb 		tmp = imageH+cropH/2;for(j=tmp;j<tmp + newImageH/2;j++){for(i=0;i<imageW;i++){ 				yuv[count++]= data[j*imageW+i];}}   		return yuv;}

用法:

将640x480裁剪成480x480时用法如下:

在onPreviewFrame(byte[] data, Camera camera)中调用

byte[] outdata2;	 byte[] outdata; outdata2 = rotateYUV420Degree90(data, 640, 480);//将640x480旋转成480x640 outdata = cropYUV420(outdata2, 480, 640,480);//将480x640裁剪成480x480 

在initVideoRecorder中

videoRecorder = new NewFFmpegFrameRecorder(strVideoPath, 480, 480, 1); 

在handleSurfaceChanged中

yuvIplImage = IplImage.create(480, 480, IPL_DEPTH_8U, 2); 

对android录制的NV21视频数据进行旋转(90,180,270)与剪切的更多相关文章

  1. Android多媒体框架总结(1) - 利用MediaMuxer合成音视频数据流程分析

    场景介绍: 设备端通过服务器传向客户端(Android手机)实时发送视频数据(H.264)和音频数据(g711a或g711u), 需要在客户端将音视频数据保存为MP4文件存放在本地,用户可以通过APP ...

  2. Android 音视频开发(四):使用 Camera API 采集视频数据

    本文主要将的是:使用 Camera API 采集视频数据并保存到文件,分别使用 SurfaceView.TextureView 来预览 Camera 数据,取到 NV21 的数据回调. 注: 需要权限 ...

  3. Android 仿微信小视频录制

    Android 仿微信小视频录制 WechatShortVideo和WechatShortVideo文章

  4. 转:android 录制视频的Demo

    转:http://blog.csdn.net/peijiangping1989/article/details/7049991 在这里给出自己的一个测试DEMO,里面注释很详细.简单的视频录制功能. ...

  5. android手机推送视频到服务端

    项目需求,android手机向服务器推送视频.苦战几个星期终于实现,现记录下来以免以后忘记. 没做过Java,也没做过Android开发,只能现学现卖.在网上找了下搭建开发a  ndroid环境资料, ...

  6. Android录制音频的三种方式

    对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...

  7. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...

  8. Android系统的五种数据存储形式(一)

    Android系统有五种数据存储形式,分别是文件存储.SP存储.数据库存储.contentprovider 内容提供者.网络存储.其中,前四个是本地存储.存储的类型包括简单文本.窗口状态存储.音频视频 ...

  9. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

随机推荐

  1. Java for LeetCode 224 Basic Calculator

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  2. Effective C++ -----条款10: 令operator=返回一个reference to *this

    比如: Widget& operator=(const Widget& rhs) { ... return* this; } 令赋值(assignment)操作符返回一个referen ...

  3. C++库(TinyXML)

    C++库(TinyXML) 什么是XML? "当 XML(扩展标记语言)于 1998 年 2 月被引入软件工业界时,它给整个行业带来了一场风暴.有史以来第一次,这个世界拥有了一种用来结构化文 ...

  4. 从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中

    1,实现功能:从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中 并实现app向后移动一个元素的位置: 2.实现思路: 01.遍历下拉菜单,添加拖拽方法,实现位置移动功能: 02.遍历app列 ...

  5. pom.xml中引入局域网仓库

    <repositories> <repository> <id>nexus</id> <name>my-nexus-repository&l ...

  6. phpexcel生成excel并下载

    Loader::import('PHPExcel.Classes.PHPExcel'); // tp5中只需将phpexcel文件放入extend文件夹中,即可采用该方法引入,需要先 use thin ...

  7. 【XLL API 函数】xlCoerce

    将 XLOPER/XLOPER12 转换为另一种类型,或是查询表格中的单元格值. 函数原型 Excel12(xlCoerce, LPXLOPER12 pxRes, 2, LPXLOPER12 pxSo ...

  8. Log4j的使用

    一,Log4j简介 日志的三个目的: 1. 监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作                      2.跟踪代码运行时轨迹,作为日后审计的依 ...

  9. 手工加载DLL

    1.为了能找到dll的函数地址,生成dll时需要将其中的函数声明为C函数(extern "C"): #ifndef __MYDLL_H#define __MYDLL_H #ifde ...

  10. 51nod1057(python2计算n!)

    题目链接:www.51nod.com/onlineJudge/questionCode.html#!problemId=1057 思路:直接for循环呗- 代码: n = int( raw_input ...