Objective-C/ALAssetslibrary - 从图像 exif 信息中获取 gps 纬度
Posted
技术标签:
【中文标题】Objective-C/ALAssetslibrary - 从图像 exif 信息中获取 gps 纬度【英文标题】:Objective-C/ALAssetslibrary - Take gps latitude from image exif informations 【发布时间】:2013-08-30 11:29:16 【问题描述】:我从一张图片中找到了一些关于使用 ALAssets 库的 gps 的 exif 信息。我可以正确显示整个退出信息,但是当我尝试仅采用纬度时,我总是收到空值。 这是关于GPS的exif信息:
"GPS" =
Altitude = 0;
AltitudeRef = 1;
DateStamp = "0111:06:09";
Latitude = "45.84633333333333";
LatitudeRef = N;
Longitude = "12.58";
LongitudeRef = E;
TimeStamp = "10:39:04.00";
;
这是我用于获取信息的代码:
__block NSConditionLock * assetsReadLock = [[NSConditionLock alloc] initWithCondition:WDASSETURL_PENDINGREADS];
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
__block ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
__block NSString *description = [[NSString alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
if (group)
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
if (asset)
NSDictionary *data = [[asset defaultRepresentation] metadata];
NSLog(@"DATA: %@", data);
NSNumber *width = [[[asset defaultRepresentation] metadata] objectForKey:@"PixelWidth"];
NSString *widthString = [NSString stringWithFormat:@"%@", width];
[widthList addObject:widthString];
NSNumber *height = [[[asset defaultRepresentation] metadata] objectForKey:@"PixelHeight"];
NSString *heightString = [NSString stringWithFormat:@"%@", height];
[heightList addObject:heightString];
NSString *latitude = [[[asset defaultRepresentation] metadata] objectForKey:@"Latitude"];
NSLog(@"latitude %@", latitude);
NSString *latitudeString = [NSString stringWithFormat:@"%@", latitude];
if(latitude != NULL)
[latitudeList addObject:latitude];
else
NSString *noLatitude = [[NSString alloc] init];
noLatitude = @"No latitude available";
[latitudeList addObject:noLatitude];
];
好吧,此时我可以轻松获取有关图像宽度和高度的信息,但是当我尝试获取纬度或经度时,我总是收到空值。我做错了什么?
感谢您的帮助!
【问题讨论】:
【参考方案1】:有一个问题。从资产库返回的默认表示已从图像中删除了诸如 EXIF 数据之类的内容,这就是您找不到它的原因。
我发现如果我手动提取构成图像的字节,我可以重建图像,然后从中获取 EXIF 数据。
这是一个函数,它将获取字节并将它们作为 NSData 对象返回:
@implementation PhotoLibrary
...
#define MAX_IMAGE_SIZE_LIKELY (700 * 1024)
static uint8_t assetBytes[MAX_IMAGE_SIZE_LIKELY];
+ (NSData*) getDataFromAsset:(ALAsset*)asset
ALAssetRepresentation* rep = [asset representationForUTI:(NSString*)kUTTypeJPEG];
if (rep != nil)
[rep getBytes:assetBytes fromOffset:0 length:[rep size] error:NULL];
return [NSData dataWithBytes:assetBytes length:[rep size]];
else
// Return nil, indicating that the image was no good.
//
return nil;
...
@end
请注意,在我的情况下,我将图像的大小限制为 700K(我有其他与您的问题无关的检查代码)。
现在,调用它的一些代码(在同一个实用程序类中)是我在 uAlertMe 中的一个函数,它扫描资产库以查找符合各种条件的图像:
// Return an array of matching images.
//
+ (void) getImagesForDate:(NSDate *)forDate
matchDateAndTime:(BOOL)matchDateAndTime
andMatchUserComment:(NSString*)userComment
withCompletionBlock:(PhotoLibraryRetrievalCompletetionBlock)completionBlock
NSMutableArray* result = [[NSMutableArray alloc] init];
if ([PhotoLibrary isAssetsLibraryAvailable])
ALAssetsGroupEnumerationResultsBlock assetEnumerator =
^(ALAsset *asset, NSUInteger index, BOOL *stop)
if(asset != NULL)
NSDictionary *dict = [asset valueForProperty:ALAssetPropertyURLs];
if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto] == YES)
// We've been asked to match the date and time, so that means
// that we need to get the image data itself so that we can
// get the EXIF metadata from within it.
//
NSData* repData = [PhotoLibrary getDataFromAsset:asset];
if (repData != nil)
NSString* comment = [EXIFUtility userCommentForPhoto:repData];
if ((userComment != nil) && [comment isEqualToString:userComment])
// OK so the user comment matches. Does the date match?
NSDate* date = [EXIFUtility dateDigitizedForPhoto:repData];
if (matchDateAndTime)
// We want an exact match.
if ([date isEqualToDate:forDate])
[result addObject:[UIImage imageWithData:repData]];
else
// We simply want a match on date, regardless of the time of day.
if ([date isSameDay:forDate])
[result addObject:[UIImage imageWithData:repData]];
;
ALAssetsLibraryGroupsEnumerationResultsBlock assetGroupEnumerator =
^(ALAssetsGroup *group, BOOL *stop)
@try
if(group != nil)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
[group enumerateAssetsUsingBlock:assetEnumerator];
completionBlock(result);
[result removeAllObjects];
[result release];
);
@catch (NSException *exception)
DDLogError(@"Exception whilst enumerating group: %@", exception);
*stop = true;
;
ALAssetsLibrary *library = [PhotoLibrary defaultAssetsLibrary];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error)
DDLogError(@"getImagesForDate:forDate matchDateAndTime: failed with error: %@", error);
completionBlock(nil);
[result removeAllObjects];
[result release];
];
else
completionBlock(nil);
[result removeAllObjects];
[result release];
可以在以下位置找到 EXIFUtility 类的 Mac OS X 版本:
EXIFUtility.h EXIFUtility.m
这些与我在 uAlertMe 中的非常相似,应该为您提供足够的信息。
【讨论】:
以上是关于Objective-C/ALAssetslibrary - 从图像 exif 信息中获取 gps 纬度的主要内容,如果未能解决你的问题,请参考以下文章