Android Camera AE和AF的设置
以geekcamera為例,當關閉閃光燈時,flash mode = 0,代表flash為off模式;
ae mode = 1,代表ae為off模式,flash state = 2,代表flash處于 ready狀態,表示沒有打閃。
當閃光燈設置為auto時,是通過設置ae mode 控制的。flash mode = 0,代表flash為off模式;
ae mode = 2,代表ae為on模式,flash state = 2,代表flash處于 ready狀態,表示沒有打閃;flash state = 3,代表flash處于 fired狀態,表示打閃了。
具體代碼邏輯
switch(flash_value) {case "flash_off":builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);break;case "flash_auto":// note we set this even in fake flash mode (where we manually turn torch on and off to simulate flash) so we// can read the FLASH_REQUIRED state to determine if flash is required/*if( use_fake_precapture || CameraController2.this.want_expo_bracketing )builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);else*/builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH);//這里FLASH_MODE可以設置為任意值,因為AE_MODE優先級高builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);break;case "flash_on":// see note above for "flash_auto" for why we set this even fake flash mode - arguably we don't need to know// about FLASH_REQUIRED in flash_on mode, but we set it for consistency.../*if( use_fake_precapture || CameraController2.this.want_expo_bracketing )builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);else*/builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH);builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);break;case "flash_torch":builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);break;case "flash_red_eye":// not supported for expo bracketing or burstif( CameraController2.this.burst_type != BurstType.BURSTTYPE_NONE )builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);elsebuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE);builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);break;case "flash_frontscreen_auto":case "flash_frontscreen_on":case "flash_frontscreen_torch":builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);break; }只要flash mode不是auto,并且需要打閃的時候,就需要做預閃(precapture)
boolean needs_flash = capture_result_ae != null && capture_result_ae != CaptureResult.CONTROL_AE_STATE_CONVERGED; if( camera_settings.flash_value.equals("flash_auto") && !needs_flash ) {// if we call precapture anyway, flash wouldn't fire - but we tend to have a pause// so skipping the precapture if flash isn't going to fire makes this fasterif( MyDebug.LOG )Log.i(TAG, "flash auto, but we don't need flash");call_takePictureAfterPrecapture = true; } else {call_runPrecapture = true; }if( call_runPrecapture ) {runPrecapture(); }runPrecapture邏輯
runPrecapture() {final CaptureRequest.Builder precaptureBuilder = mCameraDevice.createCaptureRequest(previewIsVideoMode ? CameraDevice.TEMPLATE_VIDEO_SNAPSHOT : CameraDevice.TEMPLATE_STILL_CAPTURE);precaptureBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);camera_settings.setupBuilder(precaptureBuilder, false);precaptureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);precaptureBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);precaptureBuilder.addTarget(getPreviewSurface());state = STATE_WAITING_PRECAPTURE_START;precapture_state_change_time_ms = System.currentTimeMillis();// first set precapture to idle - this is needed, otherwise we hang in state STATE_WAITING_PRECAPTURE_START, because precapture already occurred whilst autofocusing, and it doesn't occur again unless we first set the precapture trigger to idleif( MyDebug.LOG )Log.i(TAG, "capture with precaptureBuilder");captureSession.capture(precaptureBuilder.build(), previewCaptureCallback, handler);captureSession.setRepeatingRequest(precaptureBuilder.build(), previewCaptureCallback, handler);// now set precaptureprecaptureBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);captureSession.capture(precaptureBuilder.build(), previewCaptureCallback, handler); }這里將state 設置為了STATE_WAITING_PRECAPTURE_START,當captureSession.capture()調用完后,會執行到CameraCaptureSession的回調函數onCaptureCompleted(),在此回調函數中我們需要判斷AE的狀態是否等于CaptureResult.CONTROL_AE_STATE_PRECAPTURE,如果等于,那么執行takePictureAfterPrecapture()
takePictureAfterPrecapture()的邏輯
總結
以上是生活随笔為你收集整理的Android Camera AE和AF的设置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: zEngine
- 下一篇: 诺基亚N73的数个功能