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

項(xiàng)目中有一個(gè)需求是需要區(qū)分我們自己App編輯過(guò)后的照片和其他途徑得到的照片。能想到的就是操作圖片中的Exif信息,在exif信息中加入自己特有的標(biāo)識(shí),在下次從Photos里讀人的時(shí)候讀取這個(gè)標(biāo)識(shí)。

有關(guān)Exif可以看看:https://baike.baidu.com/item/Exif/422825?fr=aladdin
原本以為在exif信息里加入自己特有的字段再?gòu)腜hotos里讀出來(lái)。但是真的做起來(lái)的時(shí)候發(fā)現(xiàn)每一步都有坑:
一號(hào)坑:
iOS系統(tǒng)可能是為了隱私,讀取UIImage的exif信息的時(shí)候,會(huì)過(guò)濾,也就是說(shuō)你能拿到的信息是有限的。
二號(hào)坑:
直接保存UIImage,并不會(huì)保存你剛修改的metaData,原因大概是UIImage負(fù)責(zé)圖片的展示,不會(huì)處理meta相關(guān)信息。需要在NSData和CIImage上想辦法。
三號(hào)坑:
從系統(tǒng)相冊(cè)讀取圖片的時(shí)候,不能直接讀取生成UIImage,因?yàn)檫@里同樣只能讀取系統(tǒng)過(guò)濾后的信息,需要直接讀取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,到本地(注意不是直接保存到系統(tǒng)相冊(cè))

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

    [dest_data writeToFile:filePath atomically:YES];

c.將上一步中保存到本地的圖片,存到相冊(cè)。

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

這樣你就可以把你的信息寫入圖片的exif信息里了。
注意不能增加字段,寫入的格式必須正確,寫入的字段不能太長(zhǎng)。否則都會(huì)失敗
然后就可以在第三方軟件看到你寫入的信息了。

讀取的時(shí)候不能用requestImageForAsset接口。因?yàn)橹苯幼x出來(lái)的是UIImage,這個(gè)時(shí)候你是取不到你寫入的字段的,只有系統(tǒng)過(guò)濾后的信息。

- (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;
    }];
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容