objc,将带有曝光参数的图像保存到专辑

时间:2018-03-13 07:18:32

标签: objective-c iphone metadata ios11 exposure

我拼命地反对这个问题...

背景: 我有一个应用程序,在一个快门中拍摄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(我不知道怎么想这是可能的)。

我的发现:所以,从this帖子和this官方文档,我了解到实际上UIImage不包含元数据。

经过长时间的研究,我最终得到了两个看似位于正确路径上的点击。

一个人正在使用Photo Framework to set exposure as an asset of an image并将其添加到相册中。 Thisthis以及许多其他帖子都有助于编码。但是,我无法找到任何可以设置曝光的属性。 "阅读资产元数据" PHAsset中的属性似乎是我可以修改的,没有曝光时间。

另一个是Image I / O - > CGImageProperties - > EXIF字典键 - > kCGImagePropertyExifExposureTime。 CGImageDestinationSetProperties函数可以设置它。但这是用于将图像数据写入应用程序而不是将图像保存到相册...所以我终于找到了曝光时间属性,但我无法使用它......

我错过了什么吗?因为这看起来很容易,我的电子背景同事看着我,因为我是一个花了一天时间才能弄明白的白痴......

更新

似乎creationRequestForAssetFromImageAtFileURL:方法可以将EXIF图像存储到相册中。这篇文章(Metadata lost when saving photo using PHPhotoLibrary)表示最好使用EXIF信息临时保存图像数据,然后调用上面的方法。

我从这篇文章中获取了代码(Saving photo with metadata into Camera Roll with specific file name)并对其进行了修改。

制作专辑:

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信息,如曝光时间。还在调查它......

0 个答案:

没有答案