H Bastan,
根据您的评论:
...我想通过UIImagepicker委托方法将由设备相机捕获的图像保存到文档目录中...
看起来您的真正目标是将带有EXIF数据的图像保存到文档目录中,而不仅仅是获取带有EXIF数据的NSData对象的UIImage。在这种情况下,您可以在实现imagePickerController:didFinishPickingMediaWithInfo:
方法时执行以下操作:
UIImage *capturedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
NSFileManager *defaultManager = [NSFileManager defaultManager];
NSURL *docsURL = [[defaultManager URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSURL *outputURL = [docsURL URLByAppendingPathComponent:@"imageWithEXIFData.jpg"];
NSMutableDictionary *mutableMetadata = [metadata mutableCopy];
[mutableMetadata setObject:@(1.0) forKey:(__bridge NSString *)kCGImageDestinationLossyCompressionQuality];
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL((__bridge CFURLRef)outputURL, kUTTypeJPEG , 1, NULL);
if (imageDestination == NULL ) {
NSLog(@"Error -> failed to create image destination.");
return;
}
CGImageDestinationAddImage(imageDestination, capturedImage.CGImage, (__bridge CFDictionaryRef)mutableMetadata);
if (CGImageDestinationFinalize(imageDestination) == NO) {
NSLog(@"Error -> failed to finalize the image.");
}
CFRelease(imageDestination);
从我的测试来看,执行时间与执行以下操作的时间相同或更快:
NSData *data = UIImageJPEGRepresentation(capturedImage, 1.0)
[data writeToURL:outputURL atomically:YES]
...而且您可以保留EXIF数据!
如果您想确保界面响应,还可以将其调度到后台队列中:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Do the image saving here...
});
重要提示:您需要将ImageIO.framework
和MobileCoreServices.framework
添加到目标的构建阶段,并在执行图片保存的类中导入它们。
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
其他注意事项
据我所知,在此情况下,按照示例保存图像时不会导致世代损失。我们使用UIImage的CGImage属性,并且正如文档所述:
底层Quartz图像数据