我正在拼命对抗这个问题......
背景:我有一个应用程序可以在一个快门中拍摄 4 张不同曝光度的图像,该应用程序已设置为 AVCapturePhotoBracketSettings。我已通过调用将它们转换CMSampleBufferRef
为UIImage*
并将它们保存到我的相册中
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);// image is UIImage*
但是后来,当我将图像导出到我的 mac 时,我意识到通过右键单击图像-> 获取信息,曝光参数都已消失。我有一个 NSArray 保持 4 次曝光。我想将它们分别放在 UIImage 中,因此在将它们保存到我的相册后,它可以在 Get Info 处显示曝光时间,就像我从 iphone 内置摄像头拍摄的相册中的图像一样。
问题:我有 3 个长度为 4 个的 NSMutableArrays。一个以浮点数存储 4 个曝光数;第二个有4个CMSampleBufferRef
图像数据;最后一个有 4 个UIImage *
从第二个转换为显示在屏幕上。我需要做的就是将带有曝光编号的 UIImages 作为 jpeg 保存到我的专辑中,或者直接从 保存CMSampleBufferRef
,将我的曝光时间编号作为 jpeg 保存到我的专辑中(虽然我不知道这是可能的)。
我的发现:所以,从这篇文章和这个官方文档中,我了解到 UIImage 实际上不包含元数据。
经过长时间的研究,我最终得到了两个看似位于正确路径上的命中。
一种是使用Photo Framework 将曝光设置为图像的资产并将其添加到相册中。 This和this以及许多其他帖子有助于编码。但是,我找不到任何可以设置曝光的属性。PHAsset中的“读取资产元数据”属性似乎是我可以修改的所有内容,它没有曝光时间。
另一个是 Image I/O -> CGImageProperties -> EXIF Dictionary Keys -> kCGImagePropertyExifExposureTime。CGImageDestinationSetProperties 函数可以设置它。但这是为了将图像数据写入应用程序而不是将图像保存到相册......所以我终于找到了一个曝光时间属性,但我不能使用它......
我错过了什么??因为这看起来很容易做到,所以我的电气背景同事看着我是一个白痴,花了一天时间都想不出来......
更新:
似乎creationRequestForAssetFromImageAtFileURL:
方法将能够将带有 EXIF 的图像存储到相册。这篇文章(Metadata lost when Saving photo using PHPhotoLibrary)表示最好用EXIF信息暂时保存图片数据,然后调用上面的方法。
我从这篇文章中获取了代码(将带有元数据的照片保存到具有特定文件名的相机胶卷中)并对其进行了修改。
创建相册:
PHFetchResult *normalAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
NSLog(@"There are %lu albums fetched.", (unsigned long)normalAlbums.count);//output 0 I don't know why
_album = normalAlbums.firstObject;// this give me nil, but still can save image to the album, is this the cause of the problem?
获取 EXIF 信息:
//imageSampleBufferArray is the type of CMSampleBufferRef that has the image
CMSampleBufferRef sampleBuf = (CMSampleBufferRef)CFArrayGetValueAtIndex(imageSampleBufferArray, i);
NSDictionary* exifAttachments = (NSDictionary*)CMGetAttachment(sampleBuf, (CFStringRef)@"{Exif}", NULL);
保存图片:
+(void)saveImageWithMetaToCameraRoll:(UIImage*)image album:(PHAssetCollection *)album exif:(NSDictionary *)metadata{
NSMutableDictionary *meta = [metadata mutableCopy];
NSData *imageData = UIImageJPEGRepresentation(image, 1.0f);
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
NSString *timestamp = [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970] * 1000];
NSString *fileName = [NSString stringWithFormat:@"IMG_%@.jpeg", timestamp];
NSURL *tmpURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef) tmpURL, kUTTypeJPEG, 1, NULL);
CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) meta);
CGImageDestinationFinalize(destination);
CFRelease(source);
CFRelease(destination);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:tmpURL];
PHObjectPlaceholder *placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
if (album) {
PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
[changeRequest addAssets:@[placeholderAsset]];
}
} completionHandler:^(BOOL success, NSError *error) {
//Clean up the file:
[[NSFileManager defaultManager] removeItemAtURL:tmpURL error:nil];
if (error) {
NSLog(@"%@", error);
}
}];
}
但是,当我查看刚刚拍摄的相册中的图像时,它仍然没有任何 EXIF 信息,例如曝光时间。还在调查中...