开发过Android自定义相机的朋友估计都被相机的各种乱七八糟的旋转角度适配坑过,本文将对Camera的各种角度进行解析。
一、适配目标
根据相机旋转角度以及屏幕显示旋转角度选择相机预览数据显示到View上的预览数据显示旋转角度,使眼睛直接看到的真实画面和手机屏幕中显示的画面效果相同。
-
**相机旋转角度:**相机成像相对于手机的旋转角度,若设备已经安装上了相机,那么该相机相对于设备的旋转角度是固定的。
- Camera API获取方式
Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); Log.i(TAG, "orientation: " + info.orientation);
- Camera2 API获取方式
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); Log.i(TAG, "orientation: " + sensorOrientation ;
-
屏幕显示旋转角度:
Activity#getWindowManager()
.getDefaultDisplay()
.getRotation()
的值,可以是ROTATION_0、ROTATION_90、ROTATION_180、ROTATION_270, -
预览数据显示旋转角度:根据相机旋转角度和屏幕显示旋转角度,我们即可计算预览数据显示旋转角度。
二、发现规律
分别选择后置和前置摄像头,将手机以各个角度握持,获得相机旋转角度、屏幕显示旋转角度、预览数据如下,那么对于预览数据后前后置摄像头的镜像差别,我们可以总结出预览数据显示旋转角度:
相机 | 相机旋转角度 | 屏幕显示旋转角度 | 预览帧数据 | 预览数据显示旋转角度 |
---|---|---|---|---|
后置 | 90 | Surface.ROTATION_0 (portrait) |
![]() |
90 |
后置 | 90 | Surface.ROTATION_90 (landscape) |
![]() |
0 |
后置 | 90 | Surface.ROTATION_180 (reverse-portrait) |
![]() |
270 |
后置 | 90 | Surface.ROTATION_270 (reverse-landscape) |
![]() |
180 |
前置 | 270 | Surface.ROTATION_0 (portrait) |
![]() |
(内部镜像)90 |
前置 | 270 | Surface.ROTATION_90 (landscape) |
![]() |
(内部镜像)0 |
前置 | 270 | Surface.ROTATION_180 (reverse-portrait) |
![]() |
(内部镜像)270 |
前置 | 270 | Surface.ROTATION_270 (reverse-landscape) |
![]() |
(内部镜像)180 |
-
内部镜像:
对于后置摄像头,预览数据需要经过旋转后才能显示成正常效果,以竖屏情况为例:原始图 预览数据显示旋转角度