Confused on what object actually contains the capt

2019-09-17 15:51发布

问题:

I have a photo taking app that is using AVFoundation. So far everything works perfectly.

However, the one thing that is really confusing me is, what object is the captured image actually contained in?

I have been NSLogging all of the objects and some of their properties and I still can't figure out where the captured image is contained.

Here is my code for setting up the capture session:

self.session =[[AVCaptureSession alloc]init];


 [self.session setSessionPreset:AVCaptureSessionPresetPhoto];



 self.inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];


    NSError *error;


     self.deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.inputDevice error:&error];




     if([self.session canAddInput:self.deviceInput])
    [self.session addInput:self.deviceInput];



  self.previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];


  self.rootLayer = [[self view]layer];


  [self.rootLayer setMasksToBounds:YES];



[self.previewLayer setFrame:CGRectMake(0, 0, self.rootLayer.bounds.size.width, self.rootLayer.bounds.size.height)];


[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];



[self.rootLayer insertSublayer:self.previewLayer atIndex:0];


self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];


[self.session addOutput:self.stillImageOutput];

[self.session startRunning];


}

And then here is my code for capturing a still image when the user presses the capture button:

-(IBAction)stillImageCapture {




AVCaptureConnection *videoConnection = nil;

videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;


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.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

    [self.session stopRunning];


}

 ];}

When the user presses the capture button, and the above code executes, the captured image is successfully displayed on the iPhone screen, but I can't figure out which object is actually holding the captured image.

Thanks for the help.

回答1:

The CMSampleBuffer is what actually contains the image.

In your captureStillImageAsynchronouslyFromConnection completion handler, you'll want something like:

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage* capturedImage = [[UIImage alloc] initWithData:imageData];

My working implementation of it:

- (void)captureStillImage
{
    @try {
        AVCaptureConnection *videoConnection = nil;
        for (AVCaptureConnection *connection in _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) {

                                                                 // This is here for when we need to implement Exif stuff. 
                                                                 //CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);

                                                                 NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

                                                                 // Create a UIImage from the sample buffer data
                                                                 _capturedImage = [[UIImage alloc] initWithData:imageData];


                                                                 BOOL autoSave = YES;
                                                                 if (autoSave)
                                                                 {
                                                                     UIImageWriteToSavedPhotosAlbum(_capturedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
                                                                 }

                                                             }];
    }
    @catch (NSException *exception) {
        NSlog(@"ERROR: Unable to capture still image from AVFoundation camera: %@", exception);
    }
}