iOS中操作UIImage的Exif信息的各种坑。

作者: jlstmac | 来源:发表于2020-07-13 14:56 被阅读0次
    项目中有一个需求是需要区分我们自己App编辑过后的照片和其他途径得到的照片。能想到的就是操作图片中的Exif信息,在exif信息中加入自己特有的标识,在下次从Photos里读人的时候读取这个标识。
    

    有关Exif可以看看:https://baike.baidu.com/item/Exif/422825?fr=aladdin
    原本以为在exif信息里加入自己特有的字段再从Photos里读出来。但是真的做起来的时候发现每一步都有坑:
    一号坑:
    iOS系统可能是为了隐私,读取UIImage的exif信息的时候,会过滤,也就是说你能拿到的信息是有限的。
    二号坑:
    直接保存UIImage,并不会保存你刚修改的metaData,原因大概是UIImage负责图片的展示,不会处理meta相关信息。需要在NSData和CIImage上想办法。
    三号坑:
    从系统相册读取图片的时候,不能直接读取生成UIImage,因为这里同样只能读取系统过滤后的信息,需要直接读取NSData。
    所以修改和读取exif信息的正确方法是:
    1.修改并保存:

    取出metaData,并写入新的字典到NSData中。

        NSData *imageData = UIImageJPEGRepresentation(self, 1.0f);
        
        // create an imagesourceref
        CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL);
        
        // this is the type of image (e.g., public.jpeg)
        CFStringRef UTI = CGImageSourceGetType(source);
        
        // create a new data object and write the new image into it
        NSMutableData *dest_data = [NSMutableData data];
        CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)dest_data, UTI, 1, NULL);
        
        if (!destination) {
            NSLog(@"Error: Could not create image destination");
        }
        
        // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
        CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) container.exifData);
        BOOL success = NO;
        success = CGImageDestinationFinalize(destination);
        
        if (!success) {
            NSLog(@"Error: Could not create data from image destination");
        }
        
        CFRelease(destination);
        CFRelease(source);
        return dest_data;
    

    b.保存新的NSData,到本地(注意不是直接保存到系统相册)

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"xxx.JPG"];
    
        [dest_data writeToFile:filePath atomically:YES];
    

    c.将上一步中保存到本地的图片,存到相册。

     [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
              PHAssetChangeRequest *assetRequest = [PHAssetCreationRequest creationRequestForAssetFromImageAtFileURL: filePath];
                    PHObjectPlaceholder *placeHolder = [assetRequest placeholderForCreatedAsset];
                    savePhotoLocalIdentifier = placeHolder.localIdentifier;
                } completionHandler:^(BOOL success, NSError *_Nullable error) {}
    

    这样你就可以把你的信息写入图片的exif信息里了。
    注意不能增加字段,写入的格式必须正确,写入的字段不能太长。否则都会失败
    然后就可以在第三方软件看到你写入的信息了。

    读取的时候不能用requestImageForAsset接口。因为直接读出来的是UIImage,这个时候你是取不到你写入的字段的,只有系统过滤后的信息。

    - (PHImageRequestID)requestImageForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(UIImage *_Nullable result, NSDictionary *_Nullable info))resultHandler;
    

    可以改用requestImageDataForAsset,直接读取NSData信息。

    - (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(NSData *_Nullable imageData, NSString *_Nullable dataUTI, UIImageOrientation orientation, NSDictionary *_Nullable info))resultHandler API_DEPRECATED_WITH_REPLACEMENT("-requestImageDataAndOrientationForAsset:options:resultHandler:", ios(8, 13), tvos(8, 13)) API_UNAVAILABLE(macos);
    

    或者用

    PHContentEditingInputRequestOptions* option = PHContentEditingInputRequestOptions.new;
        option.networkAccessAllowed = YES;
        [phasset requestContentEditingInputWithOptions:option completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
            CIImage* ciimg = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
            NSDictionary = img.properties;
        }];
    

    相关文章

      网友评论

        本文标题:iOS中操作UIImage的Exif信息的各种坑。

        本文链接:https://www.haomeiwen.com/subject/mwmbcktx.html