繁体   English   中英

Objective-C / ALAssetslibrary-从图像exif信息中获取gps纬度

[英]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版本:

EXIFUtility.h EXIFUtility.m

这些与我在uAlertMe中拥有的非常相似,应该为您提供足够的信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM