将图像元数据(EXIF/TIFF/IPTC)写入OS X中的图像文件

Can*_*ğlu 6 macos iptc exif objective-c nsimage

我正在创建一个照片编辑应用程序,到目前为止,我已成功地从图像文件中读取元数据(在得到这个问题的答案之后:在OS X上打开NSImage时从EXIF读取相机数据).

source = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);
NSDictionary *props = (__bridge_transfer NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
Run Code Online (Sandbox Code Playgroud)

这会将图像文件的所有元数据复制到字典中,并且它可以很好地工作.但是,我无法找到如何将此元数据写回新创建的NSImage(或图像文件).以下是我保存文件的方法(其中img没有元数据的NSImage实例,self.cachedMetadata是从初始图像读取的字典):

NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:[img TIFFRepresentation]];
[rep setProperty:NSImageEXIFData withValue:self.cachedMetadata];
NSData *data;
if([[fileName lowercaseString] rangeOfString:@".png"].location != NSNotFound){
    data = [rep representationUsingType:NSPNGFileType properties:nil];
}else if([[fileName lowercaseString] rangeOfString:@".tif"].location != NSNotFound){
    data = [rep representationUsingType:NSTIFFFileType properties:nil];
}else{ //assume jpeg
    data = [rep representationUsingType:NSJPEGFileType properties:@{NSImageCompressionFactor: [NSNumber numberWithFloat:1], NSImageEXIFData: self.cachedMetadata}];
}

[data writeToFile:fileName atomically:YES];
Run Code Online (Sandbox Code Playgroud)

我该如何编写元数据?我以前只为JPEG编写了EXIF(字典只是以前的EXIF),但由于EXIF缺少初始图像所具有的一些字段(IPTC和TIFF标签),我需要更改我的阅读方法.现在我拥有所有数据,但我不知道如何将其写入新创建的图像文件.

谢谢,可以.

Can*_*ğlu 4

从另一个 StackOverflow 问题中找到了答案:How do you overwrite imagemetadata? :

(代码取自该问题本身并根据我的需要进行修改,其中包含我的问题的答案)

//assuming I've already loaded the image source and read the meta
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL);
CFStringRef imageType = CGImageSourceGetType(source);

//new empty data to write the final image data to
NSMutableData *resultData = [NSMutableData data];
CGImageDestinationRef imgDest = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)(resultData), imageType, 1, NULL);

//copy image data
CGImageDestinationAddImageFromSource(imgDest, source, 0, (__bridge CFDictionaryRef)(window.cachedMetadata));
BOOL success = CGImageDestinationFinalize(imgDest);
Run Code Online (Sandbox Code Playgroud)

这非常适合写回所有元数据,包括 EXIF、TIFF 和 IPTC。