Android Camera旋转角度
Arvin Hu 人气:0概述
相机图像数据都是来自于图像传感器(Image Sensor
),相机模组出厂的时候有一个默认的取景方向,一般为以下两种,请留意相机模组中小人的方向
Sensor
安装默认都是Sensor
的长边与手机的长边平行- 将上述图1的模组装入手机,结果为下图
- 两颗模组不一定如图左右摆放,也可以上下摆放,只要遵循长边对长边即可
- 此时使用后摄预览或拍照,取景方向是正常的,而手机目前相对自然方向(正常竖屏使用状态)顺时针夹角为90度,这也就是常说的 Sensor orientation 是90度
将上述图2的模组装入手机,结果为下图
- 两颗模组不一定如图左右摆放,也可以上下摆放,只要遵循长边对长边即可
- 此时使用后摄预览或拍照,若要使取景方向正常,需将手机顺时针旋转180度,此时手机相对自然方向(正常竖屏使用状态)顺时针夹角为270度,这也就是常说的
Sensor orientation
是270度
旋转角度规律
- 以下说明以
Sensor orientation
90度为例(大多数sensor都是该情况) - 屏幕显示旋转角度:Activity#getWindowManager().getDefaultDisplay().getRotation()的值,可以是
ROTATION_0
(正常竖屏使用状态)、ROTATION_90
(手机向右侧放)、ROTATION_180
(手机竖屏倒置)、ROTATION_270
(手机向左侧放) - 以屏幕角度
ROTATION_180
且使用后摄为例,其他情况类比推理
当前情况下图1模组中的小人头部朝向左边,有两种方式判断当前sensor取景后图像方向
简单方式:跟随小人的视角去看实际被拍摄的物体(假设为正常站立的人),所看到的景象是头部向右横置的人,此时若要使看到的图像恢复为正常情况,则需要将图像顺时针旋转270度
复杂方式:sensor扫描方向遵从小人头部左侧顶点向右扫描,当前情况下也就是从左下向上逐行扫描,然后依次存储到内存中,存储为图片的时候是水平从左向右存储,导致存储后的图像是头部向右横置的人,若要使图像被拍摄后为正常情况,则需要将图像顺时针旋转270度
代码实现
Camera API1(官方实现)
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); }
Camera API2
Camera API2
不需要经过任何预览画面方向的矫正,就可以正确现实画面,因为当使用 TextureView
或者 SurfaceView
进行画面预览的时候,系统会自动矫正预览画面的方向
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); // Conversion from screen rotation to JPEG orientation. static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } /** * Retrieves the JPEG orientation from the specified screen rotation. * * @param rotation The screen rotation. * @return The JPEG orientation (one of 0, 90, 270, and 360) */ private int getOrientation(int rotation) { // Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X) // We have to take that into account and rotate JPEG properly. // For devices with orientation of 90, we simply return our mapping from ORIENTATIONS. // For devices with orientation of 270, we need to rotate the JPEG 180 degrees. return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360; } final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
加载全部内容