ios - 如何通过Photokit保存图片(带有关于定位GPS的Metadata信息)到相册?
大家讲道理
大家讲道理 2017-04-17 16:50:55
[iOS讨论组]

我通过以下2种方法将有关位置的metadata信息写入照片:

  1. 将位置信息写入image,让后调用系统api将图片保存到相册

- (void)writeImageDataToSavedPhotosAlbum:(NSData *)imageData metadata:(NSDictionary *)metadata resultBlock:(PHAssetAssetBoolBlock)resultBlock
{
    __block PHObjectPlaceholder *placeholderAsset = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        UIImage *image = [self imageWithData: imageData metadata:metadata];
        [PHAssetChangeRequest creationRequestForAssetFromImage: image];
        placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
    } completionHandler:^(BOOL success, NSError *error) {
        if(success){
            PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
            completionBlock(asset, YES);
        } else {
            completionBlock(nil, NO);
        }
    }];
}

- (UIImage *)imageWithData:(NSData *)imageData metadata:(NSDictionary *)metadata
{
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
    NSMutableDictionary * sourceDic = [NSMutableDictionary dictionary];
    NSDictionary *source_metadata = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyProperties(source, NULL));
    [sourceDic addEntriesFromDictionary: metadata];
    [sourceDic addEntriesFromDictionary:source_metadata];
    
    NSMutableData *dest_data = [NSMutableData data];
    CFStringRef UTI = CGImageSourceGetType(source);
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)dest_data, UTI, 1,NULL);
    CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)sourceDic);
    CGImageDestinationFinalize(destination);
    CFRelease(source);
    CFRelease(destination);
    return [UIImage imageWithData: dest_data];
}

2.用PHAssetChangeRequest的location属性保存,代码如下:

    +(void)saveImageToCameraRoll:(UIImage*)image location:(CLLocation*)location completionBlock:(PHAssetAssetBoolBlock)completionBlock{
    __block PHObjectPlaceholder *placeholderAsset = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        newAssetRequest.location = location;
        newAssetRequest.creationDate = [NSDate date];
        placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
    } completionHandler:^(BOOL success, NSError *error) {
        if(success){
            PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
            completionBlock(asset, YES);
        } else {
            completionBlock(nil, NO);
        }
    }];
}

然后获取照片的metadata信息,发现没有关于GPS的信息,获取方法如下:

- (void)getPhotoMetadataWithAsset:(PHAsset *)asset
{
    PHImageRequestOptions *request = [PHImageRequestOptions new];
    request.version = PHImageRequestOptionsVersionCurrent;
    request.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    request.resizeMode = PHImageRequestOptionsResizeModeNone;
    request.synchronous = YES;
    
    [[PHImageManager defaultManager] requestImageDataForAsset:asset options: request resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
        CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
        if (NULL != source) {
            NSDictionary * metadataDic = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source, 0, NULL));
            NSLog(@"metada:%@",metadataDic);
            CFRelease(source);
        }
    }];
}

麻烦看下是保存metadata过程有问题?还是获取metadata有问题?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(2)
天蓬老师

找到答案了,补充上。

首先,保存方法按第二种方法保存。获取的话不需要那么麻烦,直接获取asset.location就可以了。

+(void)saveImageToCameraRoll:(UIImage*)image location:(CLLocation*)location completionBlock:(PHAssetAssetBoolBlock)completionBlock{
    __block PHObjectPlaceholder *placeholderAsset = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        newAssetRequest.location = location;
        newAssetRequest.creationDate = [NSDate date];
        placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
    } completionHandler:^(BOOL success, NSError *error) {
        if(success){
            PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
            CLLocation * location = asset.location;
            completionBlock(asset, YES);
        } else {
            completionBlock(nil, NO);
        }
    }];
}
PHPz

补充一下通过 PHObjectPlaceholder 获取 PHAsset 的操作

PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[placeholderAsset.localIdentifier] options:nil];
completionBlock(assets.firstObject, nil);
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号