尝试从UIImagePickerController中提取GPS元数据,但NSLog显示为空 [英] Trying to Pull GPS Metadata from UIImagePickerController but NSLog Shows Null

查看:354
本文介绍了尝试从UIImagePickerController中提取GPS元数据,但NSLog显示为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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(@不存在META:%@,metaDict);

在NSLog的输出中,我可以看到Working Meta包含所有关联的内容。不幸的是,不工作元输出空。从我可以告诉我需要增强图像源和CFDictionary上的选项,而不是使用零。我在正确的道路上吗?如果是这样,我应该怎样改变GPS数据? 试试获取源EXIF字典的可变副本像这样:


$ b

  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 = [元数据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元数据+其他元数据),您可以使用此数据来存储您喜欢的任何地方。

编辑:



要在您的类中添加核心位置功能,请在
标头中声明CLLocationManagerDelegate协议。在 viewDidLoad 中实例化位置管理器: CLLocationManager new];
self.locManager.delegate = self;
self.locManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
self.locManager.distanceFilter = 5.0f; //如果移动5位,位置将被更新
[self.locManager startUpdatingLocation];

并执行以下方法收集位置信息:

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

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

self.currentLocation = nil;


$ / code>

另外请确保在离开VC之前停止服务

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

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

EDIT2



好像你已经使用GusUtils的NSMutableDictionary + ImageMetadata.h类别。所以我对我的答案做了一些修改。请尝试一下。


Using UIImagePickerController I am attempting to gather GPS info from the metadata of the image. Here is my code sample:

  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);

In the output from NSLog I can see that Working Meta has all associated content. Unfortunately the Not Working Meta is outputting null. From what I can tell I need to enhance the options on the image source and CFDictionary rather than using nil. Am I on the right path? If so, what change should I make to pull the GPS data through?

解决方案

Try obtaining your mutable copy of the source EXIF dictionary like this:

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];

Now set GPS data to that EXIF dictionary (code courtesy GusUtils):

[mutableMetadata setLocation:self.currentLocation]

And finally you need to populate this data to some destination

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);

At this point the variable data should contain all information(image+GPS metadata+other metadata) and you can use this data to store wherever you like.

EDIT:

To add core location functionality in your class declare CLLocationManagerDelegate protocol in the header. Instantiate a location manager in your 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];

And implement following methods to gather location info:

-(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;
}
}

Also make sure to stop the service before leaving the VC

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

Then you can use self.currentLocation for your `location variable.

EDIT2

Ok its seems that you are already using "NSMutableDictionary+ImageMetadata.h" category from GusUtils. So I have made some modifications to my answer. Please give it a try.

这篇关于尝试从UIImagePickerController中提取GPS元数据,但NSLog显示为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆