尝试从UIImagePickerController中提取GPS元数据,但NSLog显示空

时间:2013-11-20 19:50:37

标签: ios image dictionary gps metadata

使用UIImagePickerController我试图从图像的元数据中收集GPS信息。这是我的代码示例:

  NSDictionary *imageMetadata = [info objectForKey: UIImagePickerControllerMediaMetadata];
    NSLog(@"Working META: %@",imageMetadata);

    CGDataProviderRef dataProvider = CGImageGetDataProvider(originalImage.CGImage);
    CFDataRef data = CGDataProviderCopyData(dataProvider);
    CGImageSourceRef imageSource = CGImageSourceCreateWithData(data, nil);
    NSDictionary *metaDict = (__bridge NSDictionary *)(CGImageSourceCopyProperties(imageSource, nil));
    NSLog(@"Not WOrking META: %@",metaDict);

在NSLog的输出中,我可以看到Working Meta具有所有相关内容。不幸的是,Not Working Meta输出null。据我所知,我需要增强图像源和CFDictionary的选项,而不是使用nil。我在正确的道路上吗?如果是这样,我应该做些什么来拉动GPS数据?

1 个答案:

答案 0 :(得分:1)

尝试获取源EXIF字典的可变副本,如下所示:

UIImage *image =  [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *jpeg = UIImageJPEGRepresentation(image,image.scale);
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)jpeg, NULL);
NSDictionary *metadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
NSMutableDictionary *mutableMetadata = [metadata mutableCopy];

现在将GPS数据设置为该EXIF字典(代码由GusUtils提供):

[mutableMetadata setLocation:self.currentLocation]

最后,您需要将此数据填充到某个目的地

CFStringRef UTI = CGImageSourceGetType(source);
NSMutableData *data = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef) data, UTI, 1, NULL);
CGImageDestinationAddImageFromSource(destination,source, 0, (__bridge CFDictionaryRef) mutableMetadata);
BOOL success = CGImageDestinationFinalize(destination);

此时变量data应包含所有信息(图像+ GPS元数据+其他元数据),您可以使用此data存储在任意位置。

修改

在类中添加核心位置功能声明CLLocationManagerDelegate协议 标题。在viewDidLoad

中实例化位置管理员
self.locManager = [CLLocationManager new];
self.locManager.delegate = self;
self.locManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
self.locManager.distanceFilter = 5.0f; //location would be updated if moved by 5 miter
[self.locManager startUpdatingLocation];

并实施以下方法来收集位置信息:

-(void)locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray*)locations    {
if (!locations || [locations count] == 0) {
    return;
}

CLLocation* loc = locations[[locations count] - 1];
if (loc.horizontalAccuracy < 0) {
    return;
}
self.currentLocation = loc;
}
-(void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*)oldLocation {
if (newLocation.horizontalAccuracy < 0) {
    return;
}
self.currentLocation = newLocation;
}
-(void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error {
NSLog(@"core location error: %@",[error localizedDescription]);
if ([error code] != kCLErrorLocationUnknown) {
    NSLog(@"location service will terminate now");
    self.locManager.delegate = nil;
    [self.locManager stopUpdatingLocation];

    self.currentLocation = nil;
}
}

还要确保在离开VC之前停止服务

self.locManager.delegate = nil;
[self.locManager stopUpdatingLocation];

然后你可以使用self.currentLocation作为你的`位置变量。

<强> EDIT2

好吧,您似乎已经在使用GusUtils中的“NSMutableDictionary + ImageMetadata.h”类别了。所以我对我的答案做了一些修改。请试一试。