欢迎访问我的独立博客

对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); 


posted @ 2016-11-18 18:09  github.com/starRTC  阅读(6211)  评论(0编辑  收藏  举报