
[英]Objective-C / ALAssetsLibrary - Find images informations and Exif informations
[英]Objective-C/ALAssetslibrary - Take gps latitude from image exif informations
我使用ALAssetslibrary从一张图像中找到了一些关于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];
}
}
}];
}
好了,在这一点上,我可以轻松获取有关图像宽度和高度的信息,但是当我尝试采用“纬度”或“经度”时,我总是收到null。 我做错了什么?
谢谢帮忙!
有一个陷阱。 从资产库返回的默认表示已从图像中删除了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版本:
这些与我在uAlertMe中拥有的非常相似,应该为您提供足够的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.