Android摄像头相关问题解决

前置摄像头预览倒置问题解决

近期做拍照和视频录制功能,发现谷歌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 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);
            }

你可能感兴趣的:(Android摄像头相关问题解决)