2013-08-30 98 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,應該爲你提供足夠的信息。