采集方向和预览方向有什么区别
安卓手机中,摄像头采集画面的方向,和我们预览的方向是不一致的
摄像头采集的数据一般是横向的,而人预览的方向一般为竖向的
摄像头的采集方向是固定的,不管我们怎么旋转手机,它都沿固定方向进行采集
如果我们想要采集数据能够被正确预览,就需要根据采集方向和屏幕旋转角度,对预览画面进行旋转
后置摄像头和前置摄像头预览时的区别
摄像头的“眼睛”看我们,和别人看我们的视角,是完全一样的,这个一样的视角就是摄像头的0度方向
但是我们自己预览则不同,预览是显示给自己看的,别人和摄像头看到的左边,实则是我们自己感知的右边
Android为了解决这个问题,默认是对前摄的预览画面进行了左右翻转的,而后摄的预览画面则是采集画面本身
手机正常摆放时,预览后摄画面需要旋转cameraOrientation的角度,而前摄则需要旋转360-cameraOrientation的角度,以弥补翻转带来的角度差
摄像头像素采集顺序
采集画面旋转为预览画面
注意,初始画面是以摄像头的0度视角来表示的,即手机正常摆放时,摄像头的“眼睛”看到的画面
各种角度的含义和参照规则
//摄像头朝向,前摄或后摄
int face = 0;
face = Camera.CameraInfo.CAMERA_FACING_BACK;
//摄像头采集方向,以数学方向,即逆时针方向作为正方向
//手机正常摆放,摄像头眼睛看到的画面方向为0度方向
int cameraOrientation = 0;
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(face, info);
cameraOrientation = info.orientation;
//屏幕旋转角度,也是以数学方向,即逆时针方向作为正方向
int displayRotation = 0;
Activity activity = null;
int displayRotationEnum = activity.getWindowManager().getDefaultDisplay().getRotation();
if (displayRotationEnum == Surface.ROTATION_0)
displayRotation = 0;
//对默认的预览画面进行旋转,得到正确的预览画面,这个参数适用于预览
//要根据相机采集方向和屏幕旋转角度进行计算,前摄还要考虑左右翻转造成的影响
//这个方法只旋转预览画面,不改变PreviewCallback中的回调帧数据
int previewRotation = 0;
Camera camera = null;
camera.setDisplayOrientation(previewRotation);
camera.setPreviewCallback(null);
//对采集画面进行旋转,得到正确的保存画面,这个参数适用于保存图像或推流
//要根据相机采集方向和屏幕旋转角度进行计算,前摄还要考虑左右翻转造成的影响
//这个旋转会反映到PictureCallback和PreviewCallback的回调数据当中
int frameRotation = 0;
Camera.Parameters parameters = null;
parameters.setRotation(frameRotation);
camera.takePicture(null, null, null);
计算预览时的旋转角度
//计算视频预览时,默认预览画面应该旋转的角度
public static int getPreviewRotation(int face, int cameraOrientation, int displayRotation) {
int previewRotation = 0;
if (face == Camera.CameraInfo.CAMERA_FACING_BACK)
previewRotation = (cameraOrientation - displayRotation + 360) % 360;
else
previewRotation = ((360 - cameraOrientation) - displayRotation + 360) % 360;
return previewRotation;
}
计算推流时的旋转角度
//计算推流时,采集画面应该旋转的角度
public static int getFrameRotation(int face, int cameraOrientation, int displayRotation) {
int frameRotation = 0;
if (face == Camera.CameraInfo.CAMERA_FACING_BACK)
frameRotation = (cameraOrientation - displayRotation + 360) % 360;
else
frameRotation = (cameraOrientation - (360 - displayRotation) + 360) % 360;
return frameRotation;
}