对android录制的NV21视频数据进行旋转(90,180,270)与剪切
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)与剪切的更多相关文章
- Android多媒体框架总结(1) - 利用MediaMuxer合成音视频数据流程分析
场景介绍: 设备端通过服务器传向客户端(Android手机)实时发送视频数据(H.264)和音频数据(g711a或g711u), 需要在客户端将音视频数据保存为MP4文件存放在本地,用户可以通过APP ...
- Android 音视频开发(四):使用 Camera API 采集视频数据
本文主要将的是:使用 Camera API 采集视频数据并保存到文件,分别使用 SurfaceView.TextureView 来预览 Camera 数据,取到 NV21 的数据回调. 注: 需要权限 ...
- Android 仿微信小视频录制
Android 仿微信小视频录制 WechatShortVideo和WechatShortVideo文章
- 转:android 录制视频的Demo
转:http://blog.csdn.net/peijiangping1989/article/details/7049991 在这里给出自己的一个测试DEMO,里面注释很详细.简单的视频录制功能. ...
- android手机推送视频到服务端
项目需求,android手机向服务器推送视频.苦战几个星期终于实现,现记录下来以免以后忘记. 没做过Java,也没做过Android开发,只能现学现卖.在网上找了下搭建开发a ndroid环境资料, ...
- Android录制音频的三种方式
对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活.所以有提供了另外的俩种. 下边来介绍下这三种录制的方式; 1.通过Intent调用系统的录音器功能,然后在录制 ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- Android系统的五种数据存储形式(一)
Android系统有五种数据存储形式,分别是文件存储.SP存储.数据库存储.contentprovider 内容提供者.网络存储.其中,前四个是本地存储.存储的类型包括简单文本.窗口状态存储.音频视频 ...
- Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
随机推荐
- 关于定时器 setTimeout
1.这里不考虑线程问题.把javascript想象成在时间线上运行,页面载入时,首先执行的是<script>标签中的代码,之后,将执行更多代码,当进程空闲时,下个代码就被触发并执行 如图: ...
- C#集合及特殊字符
集合里面 打印 出来时 要把 集合内的格式转化为其他格式! 壹. 集合 在.add之前 为空 数组 同样 添加元素之前 为 空(下一章超市购物例题具体体现) 1.System Collec ...
- 【QT】自己生成ui加入工程
在三个月前 我就在纠结 C++ GUI Qt 4编程这本书中2.3节 快速设计对话框这一段. 按照书上的做没有办法生成能够成功运行的程序. 这两天又折腾了好久,终于成功了. 注意事项: 1. 我之前装 ...
- 【网络】VPN
VPN: 来自百度百科 虚拟专用网络的功能是:在公用网络上建立专用网络,进行加密通讯.在企业网络中有广泛应用.VPN网关通过对数据包的加密和数据包目标地址的转换实现远程访问.VPN有多种分类方式,主要 ...
- MongoDB 基础 -安全性-(权限操作)
和其他所有数据库一样,权限的管理都差不多一样.mongodb存储所有的用户信息在admin 数据库的集合system.users中,保存用户名.密码和数据库信息.mongodb默认不启用授权认证,只要 ...
- 3ds max画曲线 设置摄像机的起始位置
参考 http://www.3dmax8.com/3dmax/2013/0916/5661.html 如果想创建曲线段,可以在单击下一个点时按住鼠标不放,继续拖曳,再拖到另一个点上,单击鼠标右键,即可 ...
- hdu1212(大数取模)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 题意:给出两个数a, b,求a%b: 思路:(c+d)%e=c%e+d%e,(c*d)%e=(c ...
- Codeforces Round #377 (Div. 2)D(二分)
题目链接:http://codeforces.com/contest/732/problem/D 题意: 在m天中要考k个课程, 数组a中有m个元素,表示第a[i]表示第i天可以进行哪门考试,若a[i ...
- KMP算法学习
kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...
- bnu24252 海盗分赃
题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=24252 这是四川2012年省赛的一道题,背景:海盗分宝藏.大概题意:给你N种价值的物品,物品有两 ...