1

我正在拼命对抗这个问题......

背景:我有一个应用程序可以在一个快门中拍摄 4 张不同曝光度的图像,该应用程序已设置为 AVCapturePhotoBracketSettings。我已通过调用将它们转换CMSampleBufferRefUIImage*并将它们保存到我的相册中

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 将曝光设置为图像的资产并将其添加到相册中。 Thisthis以及许多其他帖子有助于编码。但是,我找不到任何可以设置曝光的属性。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 信息,例如曝光时间。还在调查中...

4

0 回答 0