2014-01-28 33 views
4

我試圖在循環中使用captureStillImageAsynchronouslyFromConnection來拍攝連續(多重)高分辨率圖像,但它偶爾會暫停重新調焦。我鎖定了對焦模式(如其他的疊加過帳中所述),但這並不能防止相機偶爾重新對焦。我的代碼片段是:如何使用captureStillImageAsynchronouslyFromConnection(iOS AVFoundation)實現多重拍攝

// [self.session beginConfiguration]; 
if ([device lockForConfiguration:nil] == YES) { 
    if ([device isFocusModeSupported:AVCaptureFocusModeLocked]) { 
     [device setFocusMode:AVCaptureFocusModeLocked]; 
     NSLog(@"focus locked"); 
    } 
    if ([device isExposureModeSupported:AVCaptureExposureModeLocked]) { 
     [device setExposureMode:AVCaptureExposureModeLocked]; 
     NSLog(@"exposure locked"); 
    } 
    if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked]) { 
     [device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked]; 
     NSLog(@"white balance locked"); 
    } 
} 
// [self.session commitConfiguration]; 

for (int n = 0; n < 5; n++) { 
    [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 

     if (imageDataSampleBuffer) { 
      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 
      UIImage *image = [[UIImage alloc] initWithData:imageData]; 
      [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)image.imageOrientation completionBlock:nil]; 
     } 
    }]; 
} 

[device unlockForConfiguration] 

輸出日誌報告:

focus locked 
exposure locked 
white balance locked 

這表明重點等人應該已經成功地鎖定。

我試着用[device unlockForConfiguration][device unlockForConfiguration]包裝了鎖碼,但是這並沒有解決問題。

有人可以找出我的代碼中的錯誤或我失蹤了一步? (我知道我可以替換地實現這一點使用視頻拍攝,而不是靜物拍攝,但我需要AVCaptureSessionPresetPhoto分辨率的圖片。)任何幫助將不勝感激。謝謝。

回答

3

好吧,我想通了這個問題。 [device unlockForConfiguration]是所有captureStillImageAsynchronouslyFromConnection調用因線程和GCD任務的時間完成之前執行。一個快速的解決方案是增加一個自旋鎖,例如:

if ([device lockForConfiguration:nil]) { 
    if ([device isFocusModeSupported:AVCaptureFocusModeLocked]) 
     [device setFocusMode:AVCaptureFocusModeLocked]; 
    if ([device isExposureModeSupported:AVCaptureExposureModeLocked]) 
     [device setExposureMode:AVCaptureExposureModeLocked]; 
    if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked]) 
     [device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked]; 
} 

__block int photoCount = 5; 
for (int n = photoCount; n > 0; n--) { 
    [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 
     @synchronize(self) { 
      photoCount--; 
     } 

     if (imageDataSampleBuffer) { 
      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 
      UIImage *image = [[UIImage alloc] initWithData:imageData]; 
      [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)image.imageOrientation completionBlock:nil]; 
     } 
    }]; 
} 

while (photoCount > 0); // Spinlock until captureStillImageAsynchronouslyFromConnection captured all photos into memory 
[device unlockForConfiguration] 

可能有更優雅的解決方案在那裏(我很想聽聽他們),但一個簡單的自旋鎖的伎倆。 (另外因爲我的代碼是一個dispatch_async塊中運行,它並沒有引起用戶界面或應用程序響應任何問題。)

相關問題