2014-02-26 44 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