使用新的 PHPhotoLibrary 保存 exif 元数据

Eti*_*oël 5 objective-c ios phphotolibrary ios9

我目前正在使用AVCaptureStillImageOutput以获得全分辨率图片。我还可以使用以下代码获取 exif 元数据:

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
     { 

         CFDictionaryRef metaDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
         CFMutableDictionaryRef mutableDict = CFDictionaryCreateMutableCopy(NULL, 0, metaDict);

         NSLog(@"test attachments %@", mutableDict);

         // set the dictionary back to the buffer
         CMSetAttachments(imageSampleBuffer, mutableDict, kCMAttachmentMode_ShouldPropagate);

         NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

         UIImage *image = [[UIImage alloc] initWithData:imageData];    
         [self.delegate frameReadyToSave:image withExifAttachments: mutableDict];
     }];
Run Code Online (Sandbox Code Playgroud)

元数据位于mutableDict变量中。现在,我想用元数据将这张图片保存在两个不同的地方。我想将它保存在磁盘上的应用程序文件夹和照片库中。

现在,我尝试使用以下另一种方法保存图像(您看到的图像变量是自定义对象):

NSData* imageData = UIImageJPEGRepresentation(image.image, 1.0f);

[imageData writeToFile:image.filePath atomically:YES];

UIImageWriteToSavedPhotosAlbum(image.image, nil, nil, nil);
Run Code Online (Sandbox Code Playgroud)

现在,图像已正确保存,但不包含任何 Exif 元数据。

从我读到的内容来看,我需要使用 PHPhotoLibrary 来做到这一点,但文档对此并不太啰嗦。这是我发现的:

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image.image];      

} completionHandler:nil];
Run Code Online (Sandbox Code Playgroud)

但是如何保存元数据呢?

hol*_*ann 2

我建议你使用 ImageIO 来实现这一点:

-(void)frameReadyToSave:(UIImage*)image withExifAttachments:(NSMutableDictionary*)mutableDict
{
    NSData* imageData = UIImageJPEGRepresentation(image, 1.0f);
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
    __block NSURL* tmpURL = [NSURL fileURLWithPath:@"example.jpg"]; //modify to your needs
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef) tmpURL, kUTTypeJPEG, 1, NULL);
    CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) mutableDict);
    CGImageDestinationFinalize(destination);
    CFRelease(source);
    CFRelease(destination);
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:tmpURL];
    }   completionHandler:^(BOOL success, NSError *error) {
        //cleanup the tmp file after import, if needed
    }];
}
Run Code Online (Sandbox Code Playgroud)