2014-12-02 59 views
8

我正在編碼的Mac OS X應用程序正在使用MacBook內置的Facetime相機拍攝照片。AVCaptureDevice adjustedExposure爲False,但捕獲的圖像很暗

在MacBookAir3,2,MacBookPro8,2和MacBookPro10,2它工作正常,但在新款MacBook它需要「暗」的照片。我知道這是因爲汽車曝光,但我很難得到它的工作。 AVCaptureDeviceadjustingExposure設置爲NO,但拍攝的照片仍然完全黑暗。

代碼:setupCamera的應用程序啓動

-(void) setupCamera 
{ 
    session = [[AVCaptureSession alloc] init]; 
    session.sessionPreset = AVCaptureSessionPresetPhoto; 

    sessionInitialized = YES; 

    device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    [device lockForConfiguration:NULL]; 
    if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) 
     [device setExposureMode:AVCaptureExposureModeContinuousAutoExposure]; 

    if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) 
     [device setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; 

    if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) 
     [device setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]; 

    [device unlockForConfiguration]; 


    NSError *error = nil; 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; 
    if(error != nil) { 
     // ... 
    } 

    if([session canAddInput:input]) { 
     [session addInput:input]; 
    } else { 
     // ... 
    } 

    output = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *outputSettings = @{ AVVideoCodecKey : AVVideoCodecJPEG }; 
    [output setOutputSettings:outputSettings]; 

    if([session canAddOutput:output]) { 
     [session addOutput:output]; 
    } else { 
     // ... 
    } 
} 

時被調用一次...然後每次點擊UI中的按扣調用shootPhoto功能:

-(void) shootPhoto 
{ 
    [session startRunning]; 

    if([device lockForConfiguration:NULL]) { 
     if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) 
      [device setExposureMode:AVCaptureExposureModeContinuousAutoExposure]; 

     if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) 
      [device setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; 

     if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) 
      [device setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]; 

     [device unlockForConfiguration]; 
    } 

    if(device.adjustingFocus == NO && device.adjustingExposure == NO && device.adjustingWhiteBalance == NO) { 
     [self actuallyCapture]; 
    } else { 
     [device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:MyAdjustingExposureObservationContext]; 
     [device addObserver:self forKeyPath:@"adjustingFocus" options:NSKeyValueObservingOptionNew context:MyAdjustingFocusObservationContext]; 
     [device addObserver:self forKeyPath:@"adjustingWhiteBalance" options:NSKeyValueObservingOptionNew context:MyAdjustingWhiteBalanceObservationContext]; 
    } 
} 

-(void) actuallyCapture 
{ 
    if ([session isRunning] == NO) 
     return; 

    connection = [output connectionWithMediaType:AVMediaTypeVideo]; 
    [output captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 
     // save file etc ... 
    }]; 
} 

的想法是檢查相機設備是否正在調整對焦,曝光或白平衡。如果沒有立即致電actuallyCapture。如果正在調整 - 請添加觀察員,並致電observeValueForKeyPath致電actuallyCapture

問題是,addObserver調用永遠不會被調用,因爲設備返回所有adjustingX==NO - 但仍然捕獲的照片是黑暗的。

可能是什麼原因?我是否正確地等待白平衡和曝光調整?

很難爲我調試,因爲我只擁有那些工作正常的設備。

回答

2

我自己設法解決了這個問題。這是我怎麼做的:

設置觀察員adjustingExposureadjustingFocusadjustingWhiteBalance

[self.device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:MyAdjustingExposureObservationContext]; 
[self.device addObserver:self forKeyPath:@"adjustingFocus" options:NSKeyValueObservingOptionNew context:MyAdjustingFocusObservationContext]; 
[self.device addObserver:self forKeyPath:@"adjustingWhiteBalance" options:NSKeyValueObservingOptionNew context:MyAdjustingWhiteBalanceObservationContext]; 

要捕捉的照片初始化一個AVCaptureSession但設置了1秒延時定時器和實際捕捉到它觸發後:

-(void) shootPhoto 
{ 
    dispatch_async(self.sessionQueue, ^{ 
     if([self setupCamera]) { 
      self.sessionInitialized = YES; 
      [self.session startRunning]; 

      self.isWaitingToCaptureImage = YES; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       self.captureDelayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 
                      target:self 
                     selector:@selector(actuallyCapture) 
                     userInfo:nil 
                     repeats:NO]; 
      }); 
     } 
    }); 
} 

observeValueForKeyPath:ofObject:change:context檢查,如果所有的三個調整已經完成,如果他們是 - 取消計時器上面設置和拍攝照片:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if(!self.sessionInitialized || !self.isWaitingToCaptureImage) { 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
     return; 
    } 

    if (context != MyAdjustingExposureObservationContext && context != MyAdjustingFocusObservationContext && context != MyAdjustingWhiteBalanceObservationContext) { 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
     return; 
    } else { 
     if (self.device.adjustingExposure || self.device.adjustingFocus || self.device.adjustingWhiteBalance) { 
      NSLog(@"not ready to capture yet"); 
      return; 
     } else { 
      NSLog(@"ready to capture"); 
      if (self.captureDelayTimer && self.captureDelayTimer.isValid) { 
       [self.captureDelayTimer invalidate]; 
       self.captureDelayTimer = nil; 
      } 
      [self actuallyCaptureDispatch]; 
     } 
    } 
} 
+0

什麼是MyAdjustingWhiteBalanceObservationContext? – confile 2015-03-19 10:51:56