以前对Camera了解的不是太深入,最近有需求把人脸识别 集成到项目,必然会与Camera打交道,遇到一些坑,与大家分享一下。
一、预览方向
- Camera.CameraInfo info = new Camera.CameraInfo();
首先理解一下 info.orientation 官方解释
官方定义:orientation表示相机图像的方向。它的值是相机图像顺时针旋转到设备自然方向一致时的角度。例如假设设备是竖屏的。后置相机传感器是横屏安装的。当你面向屏幕时,如果后置相机传感器顶边的和设备自然方向的右边是平行的,则后置相机的orientation是90。如果前置相机传感器顶边和设备自然方向的右边是平行的,则前置相机的orientation是270。
画了一个简单的草图,我用两部手机进行测试,一部是华为荣耀6plus 、另一个是定做的 T6A,测试的时候把手机固定为了竖屏应用
另一款Android 机 T6A,摄像头位置比较特别,我获取的info.orientation = 0; 那意味着我不用旋转,捕获的数据,都是与屏幕方向一致的
特别说明:
对于后置相机,只需要旋转后置相机的orientation即 90即可和屏幕方向保持一致;
对于前置相机的预览方向,相机预览的图像是相机采集到的图像的镜像,由于系统对前置相机采集到的图像做了镜像,因此需要旋转 270-180,也是90度才可与屏幕方向保持一致
setDisplayOrientation(int degrees)
这个API修改的仅仅是Camera的预览方向而已,并不会影响到PreviewCallback回调、生成的JPEG图片和录像文件的方向,这些数据的方向依然会跟图像Sensor的方向一致。
二、官方推荐预览方向写法
调用this.getWindowManager().getDefaultDisplay().getRotation();
该函数的返回值,有如下四种:
Surface.ROTATION_0,Surface.ROTATION_90,Surface.ROTATION_180,Surface.ROTATION_270
其中,Surface.ROTATION_0 表示的是手机竖屏方向向上,后面几个以此为基准依次以顺时针90度递增。
三 、拍照方向
Camera的拍照方向:当你点击拍照按钮,得到的图片方向不一定与画面中预览的方向一致,这是因为拍摄的照片是将图像Sensor采集到的数据直接存储到SDCard上的,因此,Camera的拍照方向与上述的Camera的采集图像方向一致。
第一种做法
rotation 可由上面获取的预览方向获取,注意前置摄像头要翻转180度。
parameters.setRotation(rotation);//设置rotation旋转角度到Camera的参数parameters。这个旋转角度最后会写到exif信息中去 。
第二种做法
通过ExifInterface,去获取图片Orientation方向 ,然后旋转合适的角度,去展示
- 1、读取图片的旋转属性
-
/** * 读取图片的旋转的角度 * * @param path * 图片绝对路径 * @return 图片的旋转角度 */ public int getBitmapDegree(String path) { int degree = 0; try { // 从指定路径下读取图片,并获取其EXIF信息 ExifInterface exifInterface = new ExifInterface(path); // 获取图片的旋转信息 int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } 2、将图片按照某个角度进行旋转 /** * 将图片按照某个角度进行旋转 * * @param bm * 需要旋转的图片 * @param degree * 旋转角度 * @return 旋转后的图片 */ public Bitmap rotateBitmapByDegree(Bitmap bm, int degree) { Bitmap returnBm = null; // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); try { // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } catch (OutOfMemoryError e) { } if (returnBm == null) { returnBm = bm; } if (bm != returnBm) { bm.recycle(); } return returnBm; }