0

我正在创建一个执行两个图像分析功能的图像处理应用程序。一种是读取图像的RGB数据,另一种是读取EXIF数据。我正在用前置摄像头拍照,然后将其保存到文档文件夹中。为了获取 RGB 值,我以这种方式加载图像:

NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:jpgPath];
CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
const UInt8* data = CFDataGetBytePtr(pixelData);

这按预期工作,我可以获得像素数据。我的问题是收集 EXIF 数据。我正在以与 RGB 相同的方式读取图像,并且我的所有 EXIF 数据都返回为 NULL。

NSString *EXIFPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.jpg"];
NSURL *url = [NSURL fileURLWithPath:EXIFPath];

CGImageSourceRef sourceRef = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);

NSDictionary *immutableMetadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(sourceRef,0,NULL);
NSDictionary *exifDic = [immutableMetadata objectForKey:(NSString *)kCGImagePropertyExifDictionary];

NSNumber *ExifApertureValue  = [exifDic objectForKey:(NSString*)kCGImagePropertyExifApertureValue];
NSNumber *ExifShutterSpeed  = [exifDic objectForKey:(NSString*)kCGImagePropertyExifShutterSpeedValue];

NSLog(@"ExifApertureValue : %@ \n",ExifApertureValue);
NSLog(@"ExifShutterSpeed : %@ \n",ExifShutterSpeed);

如果我更改第一行代码以读取应用程序中的预加载图像,如下所示:

NSString *aPath = [[NSBundle mainBundle] pathForResource:@"IMG_1406" ofType:@"JPG"];

有用。问题是我无法预加载图像。它们必须从摄像机现场拍摄。非常感谢任何建议。谢谢你。

4

1 回答 1

1

该文件如何Test.jpg写入 Documents 目录?是用 写的UIImageJPEGRepresentation吗?如果是这样,EXIF 数据将丢失。确保为需要元数据的任何图像存储 JPEG 源。

无论发生什么,它都会在您检索到完整对象immutableMetadata和对象后立即记录它们。exifDic

NSDictionary *immutableMetadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(sourceRef,0,NULL);
NSLog(@"immutableMetadata = %@", immutableMetadata);
NSDictionary *exifDic = [immutableMetadata objectForKey:(NSString *)kCGImagePropertyExifDictionary];
NSLog(@"exifDic");

如果您的exifDic日志仅包含这三个值,则它是由一个不关心保留 EXIF 标头的函数保存的。

exifDic = {
    ColorSpace = 1;
    PixelXDimension = 1200;
    PixelYDimension = 1600;
}

另外两件事可行,但可能会更好:

(1) 不能保证 Documents 目录是 NSHomeDirectory() 的子目录。获取此文档位置的可靠方法如下:

NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
NSString *imagePath = [documentDirectory stringByAppendingPathComponent:@"Test.jpg"];

(2) 您当前从存储中加载图像字节两次,一次获取像素,一次获取元数据。将它们加载到一个NSData对象中,您只需检索一次文件。保留该NSData对象,您可以稍后保存图像而不会丢失任何细节。(这将消耗等于文件大小的内存,因此仅在需要时才保留它。)

NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
UIImage *image = [UIImage imageWithData:imageData];
// Do things involving image pixels...

CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
// Do things involving image metadata...
于 2012-04-11T09:28:01.443 回答