2012-01-10 6 views
12

Sto utilizzando il codice sorgente di qualcuno per l'acquisizione di immagini con AVCaptureSession. Tuttavia, ho trovato che l'anteprima di CaptureSessionManager è shotter e quindi l'immagine finale catturata. enter image description hereRapporto immagine iPhone acquisito da AVCaptureSession

Ho trovato che l'immagine risultante è sempre con rapporto 720x1280 = 9: 16. Ora voglio ritagliare l'immagine risultante in una UIImage con rapporto 320: 480 in modo che catturi solo la porzione visibile in previewLayer. Qualche idea? Molte grazie.

domande pertinenti in StackOverflow (buona risposta ancora): Q1, Q2

Source Code:

- (id)init { 
if ((self = [super init])) { 
    [self setCaptureSession:[[[AVCaptureSession alloc] init] autorelease]]; 
} 
return self; 
} 

- (void)addVideoPreviewLayer { 
[self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]]; 
[[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 

} 

- (void)addVideoInput { 
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
if (videoDevice) { 
    NSError *error; 


    if ([videoDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [videoDevice lockForConfiguration:&error]) { 
     [videoDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; 
     [videoDevice unlockForConfiguration]; 
    }   

    AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; 
    if (!error) { 
     if ([[self captureSession] canAddInput:videoIn]) 
      [[self captureSession] addInput:videoIn]; 
     else 
      NSLog(@"Couldn't add video input");  
    } 
    else 
     NSLog(@"Couldn't create video input"); 
} 
else 
    NSLog(@"Couldn't create video capture device"); 
} 

- (void)addStillImageOutput 
{ 
    [self setStillImageOutput:[[[AVCaptureStillImageOutput alloc] init] autorelease]]; 
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil]; 
    [[self stillImageOutput] setOutputSettings:outputSettings]; 

    AVCaptureConnection *videoConnection = nil; 
    for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) { 
    for (AVCaptureInputPort *port in [connection inputPorts]) { 
     if ([[port mediaType] isEqual:AVMediaTypeVideo]) { 
     videoConnection = connection; 
     break; 
     } 
    } 
    if (videoConnection) { 
     break; 
    } 
    } 

    [[self captureSession] addOutput:[self stillImageOutput]]; 
} 

- (void)captureStillImage 
{ 
AVCaptureConnection *videoConnection = nil; 
for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) { 
    for (AVCaptureInputPort *port in [connection inputPorts]) { 
     if ([[port mediaType] isEqual:AVMediaTypeVideo]) { 
      videoConnection = connection; 
      break; 
     } 
    } 
    if (videoConnection) { 
    break; 
} 
} 

NSLog(@"about to request a capture from: %@", [self stillImageOutput]); 
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection 
                completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 
                CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL); 
                if (exifAttachments) { 
                 NSLog(@"attachements: %@", exifAttachments); 
                } else { 
                 NSLog(@"no attachments"); 
                } 
                NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];  
                UIImage *image = [[UIImage alloc] initWithData:imageData]; 
                [self setStillImage:image]; 
                [image release]; 
                [[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil]; 
                }]; 
} 


Modifica dopo aver fatto un po 'di ricerca e sperimentazione: La proprietà "sessionPreset" di AVCaptureSession ha le seguenti costanti, che ho non ha controllato ognuno di essi, ma ha notato che la maggior parte di essi è 9:16 o 3: 4,

  • NSString * const AVCaptureSessionPresetPhoto;
  • NSString * const AVCaptureSessionPresetHigh;
  • NSString * const AVCaptureSessionPresetMedium;
  • NSString * const AVCaptureSessionPresetLow;
  • NSString * const AVCaptureSessionPreset352x288;
  • NSString * const AVCaptureSessionPreset640x480;
  • NSString * const AVCaptureSessionPresetiFrame960x540;
  • NSString * const AVCaptureSessionPreset1280x720;
  • NSString * const AVCaptureSessionPresetiFrame1280x720;

Nel mio progetto, ho l'anteprima a schermo intero (dimensione del frame è 320x480) anche: [[auto previewLayer] setVideoGravity: AVLayerVideoGravityResizeAspectFill];

L'ho fatto in questo modo: scatta la foto nella dimensione 9:16 e ritagliala a 320: 480, esattamente la parte visibile dell'anteprima. Sembra perfetto

Il pezzo di codice per il ridimensionamento e croping sostituire con il vecchio codice è macchina fotografica

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; 
UIImage *image = [UIImage imageWithData:imageData]; 
UIImage *scaledimage=[ImageHelper scaleAndRotateImage:image]; 
//going to crop the image 9:16 to 2:3;with Width fixed 
float width=scaledimage.size.width; 
float height=scaledimage.size.height; 
float top_adjust=(height-width*3/2.0)/2.0; 
[self setStillImage:[scaledimage croppedImage:rectToCrop]]; 
+0

Perché non usi un 4: 3 sessione di allenamento, che non devi ritagliare e utilizzare l'intero sensore della fotocamera? –

risposta

28

di iPhone è nativamente 4: 3. Le immagini 16: 9 che ottieni sono già ritagliate da 4: 3. Ritagliare nuovamente le immagini 16: 9 in 4: 3 non è quello che desideri. Prendi invece le immagini 4: 3 native dalla fotocamera dell'iPhone impostando self.captureSession.sessionPreset = AVCaptureSessionPresetPhoto (prima di aggiungere ingressi/uscite alla sessione).

+1

Dominik, grazie per la risposta. iPhone Camera App ha una barra degli strumenti in basso, il rapporto di anteprima è (480-44): 320 ~ = 4: 3 = 1.3333, aperto nell'app album, assomiglia all'aspetto di 480: 320 = 1,50, quindi effettivamente l'immagine è distorta già giusto? ma dal 1.333 non è molto diverso da 1.50, quindi non è così ovvio per l'utente –

+0

Sì, l'app per album inizialmente ritaglia le immagini al volo (aspetto da riempire, nessuna distorsione) per riempire l'intero schermo. Ma con un gesto di pizzico puoi vedere l'intera immagine 4: 3. –

+0

Grazie risolvere il mio problema – Naresh