2014-02-26 75 views
7

AFTER點擊拍照時,我想鎖定曝光並在曝光不再調整時關閉手電筒。所以,我添加了一個觀察者來處理adjustingExposure:AVFoundation - 如何控制曝光

- (IBAction)configureImageCapture:(id)sender 
{ 
    [self.session beginConfiguration]; 

    [self.cameraController device:self.inputDevice exposureMode:AVCaptureExposureModeAutoExpose]; 
    [self.cameraController device:self.inputDevice torchMode:AVCaptureTorchModeOn torchLevel:0.8f]; 

    [self.session commitConfiguration]; 

    [(AVCaptureDevice *)self.inputDevice addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:MyAdjustingExposureObservationContext];   
} 

這裏是observeValueForKeyPath方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if (context == MyAdjustingExposureObservationContext) { 
     if([keyPath isEqualToString:@"adjustingExposure"]) 
     { 
      BOOL adjustingExposure = [ [change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:1] ]; 

      if (!adjustingExposure) 
      { 
       [(AVCaptureDevice *)self.cameraController.inputDevice removeObserver:self forKeyPath:@"adjustingExposure"]; 

       if ([self.inputDevice isExposureModeSupported:AVCaptureExposureModeLocked]) { 
        dispatch_async(dispatch_get_main_queue(), 
            ^{ 
             NSError *error = nil; 
             if ([self.inputDevice lockForConfiguration:&error]) { 
              // 5) lock the exposure 
              [self.cameraController device:self.inputDevice exposureMode:AVCaptureExposureModeLocked]; 

              // 6) turn off the Torch 
              [self.cameraController device:self.inputDevice torchMode:AVCaptureTorchModeOn torchLevel:0.0001f]; 

              [self.inputDevice unlockForConfiguration]; 
             } 
            }); 
       }      
      } 
     } 
    } else { 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
    } 
} 

@ user3115647張貼了這個information,這正是我想要做的事。

但我的照片拍攝之前火炬關閉。

這裏是我的captureStillImageAsynchronouslyFromConnection:self.captureConnection completionHandler。該塊在拍攝圖像後發生。 observeValueForKeyPath應該在照相機在拍攝圖像之前調整曝光時發生。但是在拍攝照片之前,我的手電筒並沒有變低。這是一個計時問題,或者我沒有正確設置相機配置。

- (void)captureImage 
{ 
    // configureImageCapture has already been done 
    [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.captureConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
    { 
     if (imageSampleBuffer != NULL) 
     { 
      // Log the image properties 
      CFDictionaryRef attachmentsRef = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL); 
      NSDictionary *properties = (__bridge NSDictionary *)(attachmentsRef); 
      NSLog(@"Image Properties => %@", (properties.count) ? properties : @"none"); 
+0

好的。我知道這個問題是關於焦點和曝光,但我會首先解決曝光問題。我找到了一個答案,我試圖用曝光在這裏:http://stackoverflow.com/questions/12635446/accessing-ios-6-new-apis-for-camera-exposure-and-shutter-speed/20660981 #20660981 – Patricia

+0

我無法讓KVO按預期執行。在割炬關閉之前拍攝圖像。 – Patricia

+0

我已經更新了我現在擁有的代碼。在這裏尋找幫助。先謝謝你。 – Patricia

回答

1

我通過使用閃光燈而不是火炬發生了類似的事情。我也有一個觀察員,他也是@"videoDevice.flashActive"。我確實嘗試過使用exposureModeLocked,但它對我也不起作用。

  1. 採取的照片,閃光燈在
  2. 然後立即關閉閃光燈,並採取另一張照片的曝光有時間調整

以下可能的代碼不只是在自己的工作之前,但它與我所做的一樣簡化了。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context 
{ 
    if (context == AdjustingExposureContext) 
    { 
     self.isAdjustingExposure = [change[NSKeyValueChangeNewKey] boolValue]; 
    } 
    else if (context == FlashModeChangedContext) 
    { 
     self.isFlashActive = [change[NSKeyValueChangeNewKey] boolValue]; 
     if (!self.flashActive) 
     { 
      [self captureImage]; // QUICKLY! capture 2nd image without 
     }       // flash before exposure adjusts 
    } 
    if (!self.isAdjustingExposure && self.flashActive) 
    { 
     [self removeObserver:self forKeyPath:@"videoDevice.adjustingExposure" context:AdjustingExposureContext]; 
     [self captureImage]; // capture 1st image with the flash on 
    } 
} 

現在在回調​​,

if (self.isFlashActive) 
    [self.videoDeviceInput.device setFlashMode:NO]; 

但是,如果你需要採取多張照片,無需在降低曝光閃光,這種策略可能不起作用。

+0

我沒有進入else if(context == FlashModeChangedContext)條件。將照相機通過簡單地將其他人一樣的觀察者處理此(即,[(AVCaptureDevice *)self.inputDevice的addObserver:自forKeyPath:@ 「adjustingFlash」 選項:NSKeyValueObservingOptionNew上下文:MyAdjustingFlashObserationContext];)... – Patricia

+0

是的,沒錯,但被的keyPath'flashMode',請參閱[這裏](https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVCaptureDevice_Class/Reference/Reference.html#//apple_ref/ OCC/instp/AVCaptureDevice/flashMode) – EthanP

+0

我終於明白你的最後一句話:但是,如果你需要採取多張照片,無需在降低曝光閃光,這種策略可能不起作用。隨着每次敲擊,拍攝的圖片數呈指數增長。 – Patricia

1

這幾乎肯定是一個時間問題。在您的if區塊內撥打captureStillImageAsynchronouslyFromConnection:completionHandler:。然後在曝光被鎖定後,捕捉將始終執行。

if ([self.inputDevice isExposureModeSupported:AVCaptureExposureModeLocked]) { 
    dispatch_async(dispatch_get_main_queue(), 
     ^{ 
      NSError *error = nil; 
      if ([self.inputDevice lockForConfiguration:&error]) { 
       //code to lock exposure here 
       //take photo here 
      } 
     }); 
} 
+0

到時候我進入觀察者,我已經叫captureStillImageAsynchronouslyFromConnection:completionHandler方法。我不知道該怎麼做你的建議是什麼,我不能(對我的生活)發現,使用完成處理程序之前調用captureStillImageAsynchronouslyFromConnection的代碼示例:completionHandler方法。 – Patricia