在 OS X 上打开 NSImage 时从 EXIF 读取相机数据
Posted
技术标签:
【中文标题】在 OS X 上打开 NSImage 时从 EXIF 读取相机数据【英文标题】:Reading Camera data from EXIF while opening NSImage on OS X 【发布时间】:2013-10-29 17:49:39 【问题描述】:我正在创建一个可以打开、编辑和保存照片的照片应用。我正在使用 GPUImage 处理我的照片,并且 EXIF 数据在此过程中丢失。因此,我以这种方式打开文件时正在读取 EXIF 数据:
NSImage *img = [[NSImage alloc] initWithContentsOfURL:url];
NSImageRep *rep = [[img representations] objectAtIndex:0];
NSMutableDictionary *exif = [((NSDictionary*)[(id)rep valueForProperty:NSImageEXIFData]) mutableCopy];
它包含几乎所有的 EXIF 数据,但由于某种原因它不包括 Camera Maker 和 Camera Model。保存时我需要保留所有数据,包括这些字段。打开图像文件时如何读取整个 EXIF 数据?我已经尝试了 CF 方法:
Working with images (CGImage), exif data, and file icons
但是除了文件大小之外,我无法使用该方法读取 任何 数据。有什么方法可以完整读取EXIF数据吗?
【问题讨论】:
以什么形式读取数据? 你这是什么意思?我想按原样读取数据,这并不重要。我需要做的就是在处理照片后将确切的数据写入新的 NSImage 。目前我正在使用这种方法获得一个 NSDictionary,但它不完整。 我只知道如何在 NSOutlineView 控件中发布整个提取。 好吧,那也行,如果能比我的方法提取更多,我可以检查相关部分。 【参考方案1】:我从 Apple, Inc. 名为 ImageApp 的示例项目中提取了以下代码。因此,您需要该项目来仔细查看下面的代码。键值绑定到 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;
【讨论】:
那行得通。出于某种原因,此代码以前不起作用。也许我做错了什么。我可以在完整的字典中分别获取 TIFF/EXIF/IPTC 元数据,这比我预期的还要好。 顺便说一句,现在(因为我改变了读取方法)我正在努力将数据写入图像文件。如果您对此有任何想法,可以在这里提供帮助:***.com/questions/19692455/… ImageIOLocalizedString 和 ios14 有问题 - 找不到捆绑 ImageIO @Viktor Goltvyanitsa 查看原始主题的标签。本主题是关于 macOS 应用程序的。 @El Tomato 还有什么?到目前为止,代码本身在我的 iOS 应用程序中运行了几年。如果你愿意,那好吧,它不适用于 maccatalyst 下的 macOS。以上是关于在 OS X 上打开 NSImage 时从 EXIF 读取相机数据的主要内容,如果未能解决你的问题,请参考以下文章