将UIImage转换为NSData而不使用UIImagePngrepresentation或UIImageJpegRepresentation

我需要将UIImage转换为NSData但不使用UIImagePngRepresentationUIImageJpegRepresentation ,从photolib图像我可以使用这里提到的assetlib方法使用ALAssetsLibrary和ALAsset取出图像作为NSData ,但对于捕获的图像,assset url不存在,因此在这种情况下我需要将UIImage直接转换为带有exif数据的字节,我该如何做到这一点? 请帮忙

H巴斯坦,

根据你的评论:

…我想通过UIImagepicker委托方法在文档目录中保存捕获的图像返回的设备相机…

看起来你真正的目标是将EXIF数据保存到文档目录,而不是将UIImage作为带有EXIF数据的NSData对象。 在这种情况下,您可以在imagePickerController:didFinishPickingMediaWithInfo:的实现中执行以下imagePickerController:didFinishPickingMediaWithInfo:

 // Get your image. UIImage *capturedImage = [info objectForKey:UIImagePickerControllerOriginalImage]; // Get your metadata (includes the EXIF data). NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata]; // Create your file URL. NSFileManager *defaultManager = [NSFileManager defaultManager]; NSURL *docsURL = [[defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *outputURL = [docsURL URLByAppendingPathComponent:@"imageWithEXIFData.jpg"]; // Set your compression quuality (0.0 to 1.0). NSMutableDictionary *mutableMetadata = [metadata mutableCopy]; [mutableMetadata setObject:@(1.0) forKey:(__bridge NSString *)kCGImageDestinationLossyCompressionQuality]; // Create an image destination. CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL((__bridge CFURLRef)outputURL, kUTTypeJPEG , 1, NULL); if (imageDestination == NULL ) { // Handle failure. NSLog(@"Error -> failed to create image destination."); return; } // Add your image to the destination. CGImageDestinationAddImage(imageDestination, capturedImage.CGImage, (__bridge CFDictionaryRef)mutableMetadata); // Finalize the destination. if (CGImageDestinationFinalize(imageDestination) == NO) { // Handle failure. NSLog(@"Error -> failed to finalize the image."); } CFRelease(imageDestination); 

从我的testing来看,执行时间与做同样或者更快。

 NSData *data = UIImageJPEGRepresentation(capturedImage, 1.0); [data writeToURL:outputURL atomically:YES]; 

…你可以保存EXIF数据!

如果您想确保您的UI保持响应,您也可以将其分派到后台队列:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ // Do the image saving here... }); 

重要说明:您需要将ImageIO.frameworkMobileCoreServices.framework添加到目标的构build阶段,并将其导入到您进行图像保存的类中:

 #import <ImageIO/ImageIO.h> #import <MobileCoreServices/MobileCoreServices.h> 

其他说明这是我的理解,在这种情况下,我们不会在保存图像时产生一代的损失,如在示例中提出的。 我们正在使用UIImage的CGImage属性和文档状态:

底层的Quartz图像数据

我有类似的问题,但出于安全原因,我不想按照Wes的build议将数据写入默认文件系统。 我也想能够添加元数据到我的形象。 我的解决scheme如下:

 - (NSData *)dataFromImage:(UIImage *)image metadata:(NSDictionary *)metadata mimetype:(NSString *)mimetype { NSMutableData *imageData = [NSMutableData data]; CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mimetype, NULL); CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, uti, 1, NULL); if (imageDestination == NULL) { NSLog(@"Failed to create image destination"); imageData = nil; } else { CGImageDestinationAddImage(imageDestination, image.CGImage, (__bridge CFDictionaryRef)metadata); if (CGImageDestinationFinalize(imageDestination) == NO) { NSLog(@"Failed to finalise"); imageData = nil; } CFRelease(imageDestination); } CFRelease(uti); return imageData; } 

要使用它,你可以执行以下操作:

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata]; NSString *mimeType = @"image/jpeg"; // ideally this would be dynamically set. Not defaulted to a jpeg! // you could add to the metadata dictionary (after converting it to a mutable copy) if you needed to. // convert to NSData NSData *imageData = [self dataFromImage:image metadata:metadata mimetype:mimeType]; // ... } 

你可以尝试这样的事情。 不知道如果它是最好的方法。 但值得一试。 如果图像URL可用,则可以尝试initWithContentsOfUrl

 NSData *data = [[NSData alloc]initWithContentsOfFile:@"/Users/test/isajf/isajf/test.jpg"];