2014-04-09 4 views
6

Sto provando a catturare più foto alla massima risoluzione (AVCaptureSessionPresetPhoto) su iPhone 5s. Ho provato ad utilizzare il seguente codice:ios/iphone photo burst mode api

dispatch_semaphore_t sync = dispatch_semaphore_create(0); 
while([self isBurstModeEnabled] == YES) 
       { 
     [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
          { 

           if (imageSampleBuffer != NULL) 
           { 
            NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
            NSString *videoThumbPath = [NSString 
                   stringWithFormat:@"%@/img%d.png", 
                   burstFolderPath, 
                   index]; 

            [imageData writeToFile:videoThumbPath atomically:YES]; 
            if(0 == index) 
            { 
             [self NSLogPrint:[NSString stringWithFormat:@"Created photo at %@",videoThumbPath]]; 
            } 
           } 
           dispatch_semaphore_signal(sync); 
          }]; 
    dispatch_semaphore_wait(sync, DISPATCH_TIME_FOREVER); 
} 

Utilizzando questo codice posso ottenere circa 2 foto al secondo, nessun modo vicino le prestazioni di burst mode della app fotocamera nativa. Che cosa sto facendo di sbagliato? Inoltre ho provato ad usare il codice sopra senza il semaforo, ma in quel caso stavo avendo un comportamento strano, alcune foto mancavano (img0.png img1.png img3.png sarebbe presente ma mancerebbe img2.png). Utilizzando il secondo metodo, le prestazioni sarebbero migliori ma non uguali a quelle delle app native (nei miei test l'app per fotocamera avrebbe ottenuto circa 8,4 foto al secondo).

risposta

13

captureStillImageAsynchronouslyFromConnection:completionHandler: non è, credo, ciò che Apple sta usando per la sua modalità burst.

Invece, Apple è * che cattura i fotogrammi video a piena risoluzione (che è supportato dai 5). Ecco come:

L'AVCaptureDevice ha il suo activeFormat insieme alla piena risoluzione del sensore, allora si afferra e processo di 10 fotogrammi al secondo da AVCaptureVideoDataOutputSampleBufferDelegate s' captureOutput:didOutputSampleBuffer:fromConnection:, sparando fuori un suono dell'otturatore per ogni fotogramma grab.

È necessario disporre di un fallback (immagini a bassa risoluzione o una modalità a raffica più lenta) per i dispositivi che non supportano il video alla risoluzione completa della dimensione del sensore e/o se si desidera supportare qualsiasi cosa più vecchia di iOS 7.x.

Si noti che non è possibile avere più accessi simultanei di captureStillImageAsynchronouslyFromConnection:completionHandler: senza risultati estremamente inaspettati. Questo è il motivo per cui dovresti chiamare ogni iterazione dal precedente completionHandler (che, in sostanza, è ciò che sta facendo il tuo semaforo). Inoltre, potresti desiderare di passare da PNG come formato di file per scatti a raffica, risparmiando molto lentamente e richiedendo molte risorse di sistema: l'accumulo di 15 o 20 PNG potrebbe causare un serio dolore!

* È probabilmente facendo questo, perché potrebbe, naturalmente, utilizzare un'API privata per ottenere lo stesso risultato finale.

+0

io non cercavo quel problema preciso, ma mi chiedevo perché alcuni formati di cattura sono 'full- schermo ', e perché alcuni hanno un rapporto diverso (4: 3 vs 16: 9) ... Questo sembra essere correlato alla stabilizzazione dell'immagine, e questo spiega perché 'AVCaptureSessionPresetPhoto' non ha questo problema. (Https://www.iphonelife.com/blog/87/why-you-may-want-disable-image-stabilization-during-video-recording). Sembrerebbe logico che in modalità burst, la Stabilizzazione immagine non sia utilizzata ... – Vinzzz

+0

Gli unici formati 16: 9 sono quelli HD, che è un formato 16: 9 per definizione. Gli altri sono tutti full frame, IIRC. 'AVCaptureSessionPresetPhoto' non può essere usato per girare video, ma * puoi *, su hardware adatto, girare video alla stessa risoluzione impostando manualmente' activeFormat', non usando un preset. Con iOS 7.x i preset sono molto facoltativi. – Wildaker

+0

Quale altro modo di dire lo stesso :) Il sensore è 4: 3, quindi qualsiasi formato di output che non è 4: 3 ritaglia in realtà i dati dal sensore. Nel caso di formati 16: 9, è possibile utilizzare i pixel aggiuntivi del sensore per eseguire una stabilizzazione delle immagini e questa funzione ('AVCaptureConnection consenteVideoStabilizationWhenAvailable') è infatti SOLO disponibile per i formati 16: 9.Per quanto riguarda 'activeFormat', quello che imposti manualmente deve essere uno dei' 'formati -AVcaptureDevice' – Vinzzz

1

Utilizzare questo metodo per la modalità burst in iOS 8 e superiori:

- (void)captureStillImageBracketAsynchronouslyFromConnection:(AVCaptureConnection *)connection withSettingsArray:(NSArray *)settings completionHandler:(void (^)(CMSampleBufferRef sampleBuffer, AVCaptureBracketedStillImageSettings *stillImageSettings, NSError *error))handler NS_AVAILABLE_IOS(8_0); 

Documentation

+0

Questo per le parentesi di esposizione, non per l'acquisizione burst. Vedi http://www.digital-photo-secrets.com/tip/2111/what-is-exposure-bracketing/ per un'introduzione al bracketing dell'esposizione. – pjh68

+0

Se non si modificano le impostazioni, è possibile utilizzare la stessa impostazione per ciascuna foto ed è il modo consigliato – d0n13