Frage

I'm creating a photo app that can open photos, edit them, and save them. I'm using GPUImage to process my photos and the EXIF data is lost in the process. Because of this, I'm reading the EXIF data when opening the file this way:

NSImage *img = [[NSImage alloc] initWithContentsOfURL:url];
NSImageRep *rep = [[img representations] objectAtIndex:0];
NSMutableDictionary *exif = [((NSDictionary*)[(id)rep valueForProperty:NSImageEXIFData]) mutableCopy];

It contains almost all the EXIF data, but it doesn't include Camera Maker and Camera Model for some reason. I need to preserve all the data including those fields when saving. How can I read the whole EXIF data when opening an image file? I've tried the CF methods from this:

Working with images (CGImage), exif data, and file icons

But I can't read any data with that method except file size. Are there any methods to read the EXIF data fully?

War es hilfreich?

Lösung

I've ripped the following code out of a sample project called ImageApp by Apple, Inc. So you need that project to take a close look at the code below. The key values are bound to mTree.

// AppDelegate.h
@interface AppDelegate : NSObject {
IBOutlet NSTreeController *mTree;
NSURL *mUrl;
}

// AppDelegate.m
- (void)setPictureInfo:(NSString *)filepath {
NSURL *url = [[NSURL alloc] init];
url = [self convertpathURL:filepath:NO]; // Converting a file path to a url
[self getImageInfo:url];
}

- (void)getImageInfo:(NSURL *)url {
if (nil == url) {
    return;
}

if ([url isEqual:mUrl])
    return;

mUrl = url;   
CGImageSourceRef source = NULL;

if (url) source = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);

// CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);
if (source) {
    // get image properties (height, width, depth, metadata etc.) for display
    NSDictionary *props = (__bridge_transfer NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
    [mTree setContent:[self propTree:props]];
}
else { // couldn't make image source for image, so display nothing
    [mTree setContent:nil];
}
}

static NSString *ImageIOLocalizedString (NSString *key) {
static NSBundle *b = nil;

if (b == nil)
    b = [NSBundle bundleWithIdentifier:@"com.apple.ImageIO.framework"];

// Returns a localized version of the string designated by 'key' in table 'CGImageSource'. 
return [b localizedStringForKey:key value:key table: @"CGImageSource"];
}

- (NSArray *)propTree:(NSDictionary *)branch {
NSMutableArray *tree = [[NSMutableArray alloc] init];   
for (NSInteger i3 = 0; i3 < [branch count]; i3++) {
    NSArray *keys = [[branch allKeys] sortedArrayUsingSelector:@selector(compare:)];
    NSString *key = [keys objectAtIndex:i3];
    NSString *locKey = ImageIOLocalizedString(key);
    id obj = [branch objectForKey:key];
    NSDictionary* leaf = nil;

    if ([obj isKindOfClass:[NSDictionary class]])
        leaf = [NSDictionary dictionaryWithObjectsAndKeys:
                locKey,@"key",  @"",@"val",  [self propTree:obj],@"children",  nil];
    else
        leaf = [NSDictionary dictionaryWithObjectsAndKeys:
                locKey,@"key",  obj,@"val",  nil];

    [tree addObject:leaf];
}
return tree;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top