问题
I'm using two APIs to read EXIF data from images, which I'll call "valueForProperty:NSImageEXIFData" and "CGImageSourceCopyPropertiesAtIndex". Both provide the same EXIF data, although the second provides other data (e.g., GPS, TIFF), too.
Both give wrong values for "ApertureValue" and "MaxApertureValue", and the correct value for "FNumber". The example program that follows dumps all of the metadata returned by each method, and also invokes ExifTool. The output is summarized at the end.
(Knowing what lens I was using, ExifTool is correct when it reports MaxApertureValue as 2.8.)
Details: Xcode 4.02, OS X 10.6.7, 10.6 SDK
Anyone else notice this anomaly?
#import "ExifTestAppDelegate.h"
@implementation ExifTestAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString *path = @"/Users/marc/Pictures/iPadPhotos- overflow/Portfolio/MJR_20061221_0258.jpg";
NSData *data = [NSData dataWithContentsOfFile:path];
NSImage *img = [[[NSImage alloc] initWithData:data] autorelease];
NSImageRep *rep = [img bestRepresentationForRect:NSMakeRect(0, 0, 500, 500) context:nil hints:nil];
NSDictionary *exifDict = (NSDictionary *)[(id)rep valueForProperty:NSImageEXIFData];
NSLog(@"NSImageEXIFData: %@", exifDict);
CGImageSourceRef imgSource = CGImageSourceCreateWithData((CFDataRef)data, nil);
CFDictionaryRef dictRef = CGImageSourceCopyPropertiesAtIndex(imgSource, 0, nil);
NSLog(@"CGImageSourceCopyPropertiesAtIndex: %@", dictRef);
CFRelease(imgSource);
system([[NSString stringWithFormat:@"exiftool '%@'", path] UTF8String]);
}
@end
/*
2011-05-21 11:22:58.140 ExifTest[4510:903] NSImageEXIFData: {
ApertureValue = 6;
...
FNumber = 8;
...
MaxApertureValue = 3;
...
}
2011-05-21 11:22:58.154 ExifTest[4510:903] CGImageSourceCopyPropertiesAtIndex: {
...
"{Exif}" = {
ApertureValue = 6;
...
FNumber = 8;
...
MaxApertureValue = 3;
...
ExifTool Version Number : 8.51
...
F Number : 8.0
...
Aperture Value : 8.0
...
Max Aperture Value : 2.8
*/
Update: It's not me. Here's the EXIF data as reported by Apple's Preview app:
回答1:
Try the ImageIO framework from Quartz 2D.
Specifically CGImageSourceCopyProperties with CGImageProperties set to kCGImagePropertyExifDictionary
To get 2.8
vs 3
for the max aperture, you may need to set kCGImageSourceShouldAllowFloat
appropriately.
It's not Cocoa, but easy to use and xfer to Cocoa.
Edit
The part above about setting kCGImageSourceShouldAllowFloat
is incorrect...
I just put an f2.8 60mm Micro Nikkor prime lens on a Nikon D7000 to check this. I took one image of a very close object (3 inches away), another at mid focus (6 feet) and a third at distant focus.
The close focus image EXIF reported "Max Aperture" value of 3.2 in Preview. Photoshop allows the raw EXIF data embedded in the file to be seen. If I open the close object image in Photoshop, the embedded EXIF is shown as exif:MaxAperatureValue: 32/10
Using the same methods, the Mid focus image has a reported "Max Aperture"of 3.0 (or 30/10 in Photoshop). Only the distant focus reported "Max Aperture" value of 2.8.
So it would seem that the camera is reporting the effective max aperture of the lens given the current setting of the focus. This makes sense, because of the prevalence of variable max aperture zoom lenses. If you put a zoom lens on that has a variable max aperture (such as a Nikkor 18-200 f3.5 / f5.6) the effective max aperture at the given zoom setting and focus setting is calculated by the camera and embedded in the EXIF data. This value is corrected shown by Preview and assumably by the ImageIO framework.
See T-Stops
来源:https://stackoverflow.com/questions/6083372/mac-os-x-10-6-apis-report-incorrect-exif-data-for-aperture