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



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM