前置摄像头预览倒置问题解决
近期做拍照和视频录制功能,发现谷歌Nexus系列手机在使用前置摄像头时,预览会出现图像倒置的问题,网上Google 了一下,查到官方回应:
Because of manufacturing reasons, we needed to mount the Nexus 5X main sensor in the less-common (reverse landscape) orientation - the wires from the sensor chip wouldn't have fit otherwise. Unfortunately, our old camera API (which is deprecated, but most apps still use it) isn't terribly user-friendly, and requires application developers to explicitly set the preview rotation. On most devices, though, it turns out the default rotation is correct for a forced-landscape app, so many apps never call the display orientation method.
问题所在:前置摄像头因为硬件原因是到着装的,采用正常手机适配会存在角度偏转问题。好在谷歌提供了解决方案:
So if you do see apps with upside-down camera preview on Nexus 5X, please let the developers know about this - Android's developer relations folks are trying to reach out to apps as we find them, and LG is also helping out, but it might take a bit before everyone's up to speed on this issue.
解决方法直接上代码:
public int getCameraDisplayOrientation(Activity activity,
int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
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;
}
return result;
}
上面代码获取摄像头预览偏转的角度,只需要通过setDisplayOrientation方法重新设置一下预览角度即可:
rotation = getCameraDisplayOrientation(mContext, cameraFacing);
mCamera.setDisplayOrientation(rotation);
同时在播放拍摄好的视频时,也要注意设置输出角度,否则也会出现图像偏转问题
mRecorder.setOrientationHint(360 - rotation);//输出角度
视频预览尺寸设置,导致播放失败或播放模糊问题
录制好的视频播放预览时,如果设置的播放尺寸手机不存在,会导致调用出错而无法播放视频,尺寸过小是也会出现播放模糊问题,解决方案是根据手机的硬件配置获取最合适的尺寸进行播放,代码如下:
//获取摄像头支持的最接近的尺寸
public Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
Camera.Size recordSize = getOptimalPreviewSize(mCamera.getParameters().getSupportedPreviewSizes(), 640, 480);
if (recordSize != null) {
//设置要捕获的视频的宽度和高度
mSurfaceHolder.setFixedSize(recordSize.width, recordSize.height);
mRecorder.setVideoSize(recordSize.width, recordSize.height);
}
网友评论