2014-01-28 2 views
4

captureStillImageAsynchronouslyFromConnection 루프를 사용하여 연속 (멀티 샷) 고해상도 이미지를 캡처하려고하지만 가끔 일시 중지하여 다시 초점을 맞 춥니 다. 다른 stackoverflow 게시에 설명 된대로 초점 모드를 잠 갔지만 카메라가 가끔 초점을 다시 잡는 것을 막지는 못했습니다. 내 코드는 다음과 같습니다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]은 스레드와 GCD 작업의 타이밍으로 인해 captureStillImageAsynchronouslyFromConnection 호출이 모두 완료되기 전에 실행 중이었습니다.

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 블록 내에서 실행되기 때문에 UI 또는 앱 응답성에 문제가 발생하지 않았습니다.)