我正在创建一个图像处理应用程序,它可以执行两个图像分析功能。一种是读取图像的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"];
有效。问题是我无法预加载图像。它们必须从相机中取出。任何建议都非常感谢。谢谢。
答案 0 :(得分: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...