Android Camera2 API的ISO和对焦设置

来源:互联网 发布:hotel california知乎 编辑:程序博客网 时间:2024/05/18 06:21

       最近工作中遇到Android Camera2的开发需求,特别是iso、对焦的手动设置。找了些资料,也下载了一些demo(很多demo都是没运行出来的),最后终于挣扎着达到了想要的效果。虽然还有很大的改进空间,不过还是先分享给需要的朋友吧。

       查找资料的过程中百度到2 篇资料,一开始觉得也没什么,现在想想,关键的信息其实对方也已阐明。

1.How to control iso manually in camera2, android;

2.Android Camera2 Manual Settings

主要内容:

If your device supports manual ISO control (MANUAL_SENSOR capability),

you can turn off auto-exposure by either disabling all automatics,

or by just disabling auto-exposure, leaving auto-focus and auto-white-balance running.

Once you've disabled AE, you can manually control exposure time, sensitivity (ISO),

you have to control all 3 parameters (there are defaults if you never set one, but they won't vary automatically). 

You can copy the last-good values for these from the last CaptureResult before you turn off AE, to start with.


you can switch to a MANUAL_TEMPLATE and together with the setted value, put a default values to your builder to avoid a black preview without parameters.


以下是关键代码:

 private void createCameraPreviewSession() {        try {            SurfaceTexture texture = mTextureView.getSurfaceTexture();            assert texture != null;            // We configure the size of default buffer to be the size of camera preview we want.            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());            // This is the output Surface we need to start preview.            Surface surface = new Surface(texture);            // We set up a CaptureRequest.Builder with the output Surface.            mPreviewRequestBuilder                    = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);            mPreviewRequestBuilder.addTarget(surface);            initPreviewBuilder();            mState = STATE_PREVIEW;            // Here, we create a CameraCaptureSession for camera preview.            mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),                    new CameraCaptureSession.StateCallback() {                        @Override                        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {                            // The camera is already closed                            if (null == mCameraDevice) {                                return;                            }                            // When the session is ready, we start displaying the preview.                            mCaptureSession = cameraCaptureSession;                            try {                                // Finally, we start displaying the camera preview.                                mPreviewRequest = mPreviewRequestBuilder.build();                                mCaptureSession.setRepeatingRequest(mPreviewRequest,                                        mCaptureCallback, mBackgroundHandler);                            } catch (CameraAccessException e) {                                e.printStackTrace();                            }                        }                        @Override                        public void onConfigureFailed(                                @NonNull CameraCaptureSession cameraCaptureSession) {                            showToast("Failed");                        }                    }, null            );        } catch (CameraAccessException e) {            e.printStackTrace();        }    }    private int isoValue = 0;    private float focusValue = 0.0f;    public void createCameraPreviewSession_ISO() {        try {            mPreviewRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, isoValue);            mPreviewRequest = mPreviewRequestBuilder.build();            mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);        }catch (CameraAccessException e) {            e.printStackTrace();        }    }    public void createCameraPreviewSession_FOCUS() {        try {            mPreviewRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusValue);            mPreviewRequest = mPreviewRequestBuilder.build();            mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);        }catch (CameraAccessException e) {            e.printStackTrace();        }    }
    //base on Nexcus 6P:[0,10]    private float valueAF = 0.0f;    //base on Nexcus 6P:[12,-12]    private int valueAE = 0;    //base on Nexcus 6P:[234324552,9516]    private long valueAETime = (234324552 - 9516) / 2;    //base on Nexcus 6P:[60,7656]    private int valueISO  = 60;    private void initPreviewBuilder() {        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_OFF);        mPreviewRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, valueAF);        mPreviewRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, valueAETime);        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, valueAE);        mPreviewRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, valueISO);    }
    @Override    public void onStopTrackingTouch(SeekBar seekBar) {        switch (seekBar.getId()) {            case R.id.iso: {                Range<Integer> range = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);                int max = range.getUpper();                int min = range.getLower();                isoValue = ((seekBar.getProgress() * (max - min)) / 100 + min);                createCameraPreviewSession_ISO();                break;            }            case R.id.focus: {                float distance = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);                focusValue = seekBar.getProgress() * distance / 100;                createCameraPreviewSession_FOCUS();                break;            }            default:                break;        }    }
       我的测试机是Nexcus 6P,所以上面的一些数据也是Nexcus 6P上获取的数据。

      上面的代码是根据android-Camera2Basic-master修改的,因此也就不过多说明代码了,毕竟上面也写得很清楚了。

       最后,附上自己写的demo:https://github.com/wingskyer/android-Camera2Basic-master。








1 0
原创粉丝点击