美文网首页
Android Camera2采坑记录

Android Camera2采坑记录

作者: 秋枫叨叨 | 来源:发表于2017-08-17 17:27 被阅读1412次

    问题1 相机预览画面变形

    造成原因:

    画面显示空间的长宽比例与相机预览的分辨率比例不一致

    解决方案:

    根据SurfaceView的长宽比例选择合适的相机分辨率,并调整SurfaceView的显示比例(因为相机预览的分辨率是固定的那几组,而你无法百分百确定选择相机的分辨率会和你SurfaceView的比例一致,所以,选择完相机预览分辨率后,你还得调整显示画面的比例)

    /**
         * 选择合适的预览尺寸
         *
         * @param choices
         * @param textureViewWidth
         * @param textureViewHeight
         * @return
         */
        private Size chooseOptimalSize(Size[] choices, int textureViewWidth, int textureViewHeight) {
            //先查找preview中是否存在与surfaceview相同宽高的尺寸
            for (Size option : choices) {
                if ((option.getWidth() == textureViewWidth) && (option.getHeight() == textureViewHeight)) {
                    return option;
                }
            }
            // 得到与传入的宽高比最接近的size
            float reqRatio = ((float) textureViewWidth) / textureViewHeight;
            float curRatio, deltaRatio;
            float deltaRatioMin = Float.MAX_VALUE;
            Size retSize = null;
            for (Size size : choices) {
                curRatio = ((float) size.getWidth()) / size.getHeight();
                deltaRatio = Math.abs(reqRatio - curRatio);
                if (deltaRatio < deltaRatioMin) {
                    deltaRatioMin = deltaRatio;
                    retSize = size;
                }
            }
            return retSize;
        }
    

    问题2 Camera2手动点击聚焦失效

    问题详情:参考Camera2-master项目手动点击聚焦,设置完CaptureRequest.Builde所需要手动聚焦的参数后,使用CameraCaptureSession.setRepeatingRequest()请求相机聚焦于某一区域,小米手机上面测试失效。然后并不是所有的设备都会失效,我所使用的另一台华为mate9设备能够正常聚焦。
    代码如下:

            //List of metering areas to use for auto-exposure adjustment. 自动曝光
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions);
            //传感器所需要捕获的区域
            mCaptureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion);
    //        float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
    //        float num = (((float) 1) * minimumLens / 100);
    //        mCaptureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.0f);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            updatePreview(mCameraCaptureSession);
    
    /**
         * 更新相机预览
         *
         * @param session
         */
        private void updatePreview(CameraCaptureSession session) {
            try {
                session.setRepeatingRequest(mCaptureRequestBuilder.build(), null, mChildHander);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                //CameraDevice was already closed
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    造成原因

    具体的原因还没有找到,查看谷歌官方文档,比较了一下setRepeatingRequest 和capture方法的区别,一个是他们的优先级不一样,后者要高于前者,后来再仔细想想,请求聚焦应该只是某一刻的时候发生的事情,也不应该是连续的事情,所以使用capture还是挺合理的。

    解决方案:

    在谷歌上找到关于AF的一些问题的方法,尝试使用CameraCaptureSession.capture()方法去请求需要手动聚焦的区域,在小米手机上面测试,效果显著,问题解决。

    //List of metering areas to use for auto-focus  用来自动对焦的测量面积列表
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, mAFRegions);
            //List of metering areas to use for auto-exposure adjustment. 自动曝光
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions);
            //传感器所需要捕获的区域
            mCaptureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion);
    //        float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);
    //        float num = (((float) 1) * minimumLens / 100);
    //        mCaptureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.0f);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
    
            try {
                mCameraCaptureSession.capture(mCaptureRequestBuilder.build(),null,mChildHander);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
    

    相关文章

      网友评论

          本文标题:Android Camera2采坑记录

          本文链接:https://www.haomeiwen.com/subject/fohwrxtx.html