EXIF 数据不与图像一起保存?

Posted

技术标签:

【中文标题】EXIF 数据不与图像一起保存?【英文标题】:EXIF Data not saving with image? 【发布时间】:2018-10-16 07:12:57 【问题描述】:

我想在特定专辑中保存一些带有图像的字符串。 所以我用[[phphotoLibrary sharedPhotoLibrary] performChanges:^ 添加资产。

但是当我从相册中获取照片时,它没有 exif 数据。

我的保存 EXIF 数据的代码在这里。请大家回答。

- (void)addImageToCameraRoll:(UIImage *)image didfinish:(NSString *)albumName 

    void (^saveBlock)(PHAssetCollection *assetCollection) = ^void(PHAssetCollection *assetCollection) 

        NSData* jpeg = UIImageJPEGRepresentation(image, 1.0f);

        CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) jpeg, NULL);
        CFStringRef imageType = CGImageSourceGetType(source);
        NSDictionary *metadata = (NSDictionary *) CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source, 0, NULL));
        NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];

        NSMutableDictionary *EXIFDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];
        NSMutableDictionary *GPSDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyGPSDictionary]mutableCopy];

        if(!EXIFDictionary)
            //if the image does not have an EXIF dictionary (not all images do), then create one for us to use
            EXIFDictionary = [NSMutableDictionary dictionary];
        

        if(!GPSDictionary)
            GPSDictionary = [NSMutableDictionary dictionary];
        

        [GPSDictionary setValue:[NSNumber numberWithFloat:1.1] forKey:(NSString*)kCGImagePropertyGPSLatitude];
        [GPSDictionary setValue:[NSNumber numberWithFloat:2.2] forKey:(NSString*)kCGImagePropertyGPSLongitude];
        [EXIFDictionary setValue:@"my string to exif" forKey:(NSString *)kCGImagePropertyExifUserComment];
        [metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary];
        [metadataAsMutable setObject:GPSDictionary forKey:(NSString *)kCGImagePropertyGPSDictionary];

        NSMutableData *resultData = [NSMutableData data];
        CGImageDestinationRef imgDest = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)(resultData), imageType, 1, NULL);

        //copy image data
        CGImageDestinationAddImageFromSource(imgDest, source, 0, (CFDictionaryRef) metadataAsMutable);
        BOOL success = CGImageDestinationFinalize(imgDest);
        UIImage * image1 = [[UIImage alloc] initWithData:resultData];



        //Add assets
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
                        PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image1];



                        PHObjectPlaceholder *assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset;
                        PHAssetCollectionChangeRequest *albumChangeRequest =
                        [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
                        [albumChangeRequest addAssets:@[ assetPlaceholder ]];

        

                completionHandler:^(BOOL success, NSError *error) 
                         if (!success) 
                                NSLog(@"Error creating asset: %@", error);
                         else

                         
                ];
    ;


    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
    fetchOptions.predicate = [NSPredicate predicateWithFormat:@"localizedTitle = %@", albumName];

    PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:fetchOptions];

    if (fetchResult.count > 0) 
        saveBlock(fetchResult.firstObject);
    
    else 
        __block PHObjectPlaceholder *albumPlaceholder;
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^
            PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName];
            albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection;

         completionHandler:^(BOOL success, NSError *error) 
            if (success) 
                PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[albumPlaceholder.localIdentifier] options:nil];
                if (fetchResult.count > 0) 
                    saveBlock(fetchResult.firstObject);
                
             else 
                NSLog(@"Error creating album: %@", error);
            
        ];
    

我正在使用 PHImageManager 获取图像。

【问题讨论】:

【参考方案1】:

要使用 Photos 框架保存带有照片的细节,您必须将图像写入临时文件并使用 CGImageDestinationAddImage 将元数据添加到临时文件中。

然后您可以使用 [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL] 从临时文件中读取数据并将其保存到照片库中。

【讨论】:

看这行 UIImage * image1 = [[UIImage alloc] initWithData:resultData];我已经通过保存新图像来做到这一点。但不工作。如果你有工作代码共享 请使用 [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:tmpURL];而不是 [PHAssetChangeRequest creationRequestForAssetFromImage:image1];

以上是关于EXIF 数据不与图像一起保存?的主要内容,如果未能解决你的问题,请参考以下文章

在调整图像大小时保留 exif 数据

为图像设置 exif 数据时出现问题

在图像上设置 Exif 数据总是在 Android 7 上返回错误

BGRA 的 Tiff 或 Exif 标签

camera2 如何从图像读取器侦听器中的 YUV_420_888 图像中获取 Exif 数据

使用 C++ 修改 EXIF 数据