7

I previously had this code to capture a single image from a Mac's iSight camera using QTKit:

- (NSError*)takePicture
{    
    BOOL success;
    NSError* error;

    captureSession = [QTCaptureSession new];
    QTCaptureDevice* device = [QTCaptureDevice defaultInputDeviceWithMediaType: QTMediaTypeVideo];

    success = [device open: &error];
    if (!success) { return error; }

    QTCaptureDeviceInput* captureDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice: device];
    success = [captureSession addInput: captureDeviceInput error: &error];
    if (!success) { return error; }

    QTCaptureDecompressedVideoOutput* captureVideoOutput = [QTCaptureDecompressedVideoOutput new];
    [captureVideoOutput setDelegate: self];

    success = [captureSession addOutput: captureVideoOutput error: &error];
    if (!success) { return error; }

    [captureSession startRunning];
    return nil;
}
- (void)captureOutput: (QTCaptureOutput*)captureOutput
  didOutputVideoFrame: (CVImageBufferRef)imageBuffer
     withSampleBuffer: (QTSampleBuffer*)sampleBuffer
       fromConnection: (QTCaptureConnection*)connection
{
    CVBufferRetain(imageBuffer);

    if (imageBuffer) {
        [captureSession removeOutput: captureOutput];
        [captureSession stopRunning];

        NSCIImageRep* imageRep = [NSCIImageRep imageRepWithCIImage: [CIImage imageWithCVImageBuffer: imageBuffer]];

        _result = [[NSImage alloc] initWithSize: [imageRep size]];
        [_result addRepresentation: imageRep];

        CVBufferRelease(imageBuffer);

        _done = YES;
    }
}

However, I found today that QTKit has been deprecated and so we must now use AVFoundation. Can anyone help me convert this code to its AVFoundation equivalent? It seems as though many methods have the same name, but at the same time, a lot is different and I'm at a complete loss here... Any help?

Alex
  • 5,009
  • 3
  • 39
  • 73

1 Answers1

10

Alright, I found the solution!! Here it is:

- (void)takePicture
{
    NSError* error;
    AVCaptureDevice* device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
    AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice: device error: &error];
    if (!input) {
        _error = error;
        _done = YES;
        return;
    }

    AVCaptureStillImageOutput* output = [AVCaptureStillImageOutput new];
    [output setOutputSettings: @{(id)kCVPixelBufferPixelFormatTypeKey: @(k32BGRAPixelFormat)}];

    captureSession = [AVCaptureSession new];
    captureSession.sessionPreset = AVCaptureSessionPresetPhoto;

    [captureSession addInput: input];
    [captureSession addOutput: output];
    [captureSession startRunning];

    AVCaptureConnection* connection = [output connectionWithMediaType: AVMediaTypeVideo];
    [output captureStillImageAsynchronouslyFromConnection: connection completionHandler: ^(CMSampleBufferRef sampleBuffer, NSError* error) {
        if (error) {
            _error = error;
            _result = nil;
        }
        else {
            CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

            if (imageBuffer) {
                CVBufferRetain(imageBuffer);

                NSCIImageRep* imageRep = [NSCIImageRep imageRepWithCIImage: [CIImage imageWithCVImageBuffer: imageBuffer]];

                _result = [[NSImage alloc] initWithSize: [imageRep size]];
                [_result addRepresentation: imageRep];

                CVBufferRelease(imageBuffer);
            }
        }

        _done = YES;
    }];
}

I hope this helps whoever has any problems in doing this same thing.

Alex
  • 5,009
  • 3
  • 39
  • 73
  • This link from Apple also provides instructions on transitioning from `QTKit` to `AVFoundation`: https://developer.apple.com/library/mac/technotes/tn2300/_index.html – Dov Oct 24 '14 at 14:46
  • 1
    Thanks so much! But one question: my photos are coming out very very dark. Did you have this problem, or find a way to lengthen the exposure time? – Stan James Dec 08 '14 at 23:08
  • same problem here, very dark – famfamfam Feb 04 '21 at 08:53