2013-08-30 71 views
1

我从一张图像中发现了一些关于使用ALAssetslibrary的gps的exif信息。我可以正确显示整个退出信息,但是当我尝试仅取得纬度时,我总是收到空。 这是关于GPS的EXIF信息:Objective-C/ALAssetslibrary - 从图像exif信息中获取gps纬度

"{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]; 
       } 
      } 
     }]; 
    } 

好了,在这一点上,我可以很容易地花费大约宽度信息和图像的高度,但当我尝试采取纬度或经度我总是收到空。我做错了什么?

感谢您的帮助!

回答

0

有一个问题。从资产库返回的默认表示从图像中剥离了诸如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]; 
    } 
} 

在Mac OS X版本该EXIFUtility类,可以发现:

EXIFUtility.h EXIFUtility.m

这些都是非常相似,我在uAlertMe,应该为你提供足够的信息。