关于android的YuvImage旋转

YuvImage 在安卓中不常用,远远没有Bitmap那么常见。


我搞了那么久安卓开发,因为之前没有接触相机相关的开发,所以这个YuvImage还是第一次碰到。


其中是在Camera类的的PreviewCallback回调中



这个接口回调的是相机的预览图像,但是是YUV格式的,起初我想吧这个byte数组转换成bitmap,用BitmapFactory转后拿到null的对象

显然,这个byte数组不一样。


然后我利用YuvImage对象的compressToJpeg方法生成图片文件保存在本地,算是看清了图片的内容


YuvImage对象内部的方法少的可怜,感觉只能单方向的转成文件流,然后文件再转成bitmap。要是从bitmap回到YuvImage感觉不太可能。(知道的大神可以说下)


贴上YuvImage格式byte数组转成文件的办法:


public static void saveMyBitmap(String filePath,byte[] data,int width,int high){
		File f = new File(filePath);
		try {
			f.createNewFile();
		} catch (IOException e) {
		}
		FileOutputStream fOut = null;
		try {
			fOut = new FileOutputStream(f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		int w = cameraManager.getPreviewWidth();
		int h = cameraManager.getPreviewHeight();
		YuvImage yuvImage = new YuvImage(data,ImageFormat.NV21,<span style="font-family: Arial, Helvetica, sans-serif;">width</span><span style="font-family: Arial, Helvetica, sans-serif;">,high,null);</span>
		try {
			yuvImage.compressToJpeg(new Rect(0,0,w,h),50,fOut);
		}catch (Exception e){
			
		}
		try {
			fOut.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			fOut.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

再提及一下,为什么要旋转YuvImage,因为安卓的摄像Camera天生是横的,当用竖屏牌照或者摄像的时候,需要设置

Camera.setDisplayOrientation(90);

这样,照片的方向是对的,但是尺寸缺不对劲,这时,surfaceView的宽高比和Camera的宽高比刚好是倒数关系,预览图的输出倒了,相机还是原来的,这个貌似无法改变。就此时你拍摄一张照片,拿到的bitmap也是有90度的角度差别和你竖屏所见。后续处理bitmap旋转并不麻烦:

 

@Override  
public void onPictureTaken(byte[] data, Camera camera) {  
   //将得到的照片进行270°旋转,使其竖直  
   Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);  
   Matrix matrix = new Matrix();  
   matrix.preRotate(270);  
   bitmap = Bitmap.createBitmap(bitmap ,0,0, bitmap .getWidth(), bitmap
.getHeight(),matrix,true);  
};


但是处理YuvImage旋转就蛋疼了,我找了很久发现没有找到。准备放弃的时候去stackoverflow看了一下问题和我类似:

https://stackoverflow.com/questions/14167976/rotate-an-yuv-byte-array-on-android


贴上旋转YuvImage的核心代码,谢谢大神:


private byte[] rotateYUV420Degree90(byte[] data, int imageWidth, int imageHeight)
	{
		byte [] yuv = new byte[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;
	}

亲测有效,转完还是YuvImage格式的byte数组,屌炸了


以上,转载请注明出处:http://blog.csdn.net/illidantao/article/details/51366047


  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值