1

I am trying to get the exposure time from an image captured using AVFoundation. When I followed the 2010's WWDC instruction about retrieving useful image metadata from CMSampleBuffer like this:

-(void)captureStillImageWithCompletion:(completion_exp)completionHandler
{
AVCaptureConnection *connection = [stillImage connectionWithMediaType:AVMediaTypeVideo];

typedef void(^MyBufBlock)(CMSampleBufferRef, NSError*);

MyBufBlock h = ^(CMSampleBufferRef buf, NSError *err){
    CFDictionaryRef exifAttachments = CMGetAttachment(buf, kCGImagePropertyExifDictionary, NULL);
    if(exifAttachments){
        NSLog(@"%@",exifAttachments);
    }

    if(completionHandler){
        completionHandler();
    }
};

[stillImage captureStillImageAsynchronouslyFromConnection:connection completionHandler:h];
}

I had an error on the CFDictionaryRef line:

Cannot initialize a variable of type'CFDictionaryRef (aka 'const __CFDictionary*') with an rvalue of type CFTypeRef..

So I followed a solution in the internet by casting it like this:

CFDictionaryRef exifAttachments = (CFDictionaryRef)CMGetAttachment(buf, kCGImagePropertyExifDictionary, NULL);

And now it gives me another error: Undefined symbols for architecture armv7s

(Apple Mach-o Linker Error: "_kCGImagePropertyExifDictionary", referenced from:)
(Apple Mach-o Linker Error: "_CMGetAttachment", referenced from:)

I don't understand what went wrong with my program. Anybody has any idea?

stkent
  • 19,772
  • 14
  • 85
  • 111
yonasstephen
  • 2,645
  • 4
  • 23
  • 48

3 Answers3

3

Modified version of Philli's answer for Swift4:

var exifEd: Double?
if let metadata = CMGetAttachment(sampleBuffer, key: "{Exif}" as CFString, attachmentModeOut: nil) as? NSDictionary {
    if let exposureDurationNumber = metadata.value(forKey: "ExposureTime") as? NSNumber {
        exifEd = exposureDurationNumber.doubleValue
    }
}
Volodymyr Kulyk
  • 6,455
  • 3
  • 36
  • 63
2

EDIT: You have to include ImageIO library and header to make this key work. If you do not want to do that you can use this:

There's something about the key I think. This worked for me:

CFDictionaryRef exifAttachments = CMGetAttachment(buf, (CFStringRef)@"{Exif}", NULL);
stkent
  • 19,772
  • 14
  • 85
  • 111
Laz
  • 538
  • 7
  • 12
2

Struggling with that too, I found out that you can simply cast the Exif attachment as an NSDictionary. I hope this will help anyone.

let metadata = CMGetAttachment(image, "{Exif}", nil ) as! NSDictionary
let buf = metadata.valueForKey("ExposureTime") as! NSNumber
let xposure:Double = buf.doubleValue
Philli
  • 131
  • 7