2013-08-30 3 views
1

ALAssetslibrary를 사용하여 gps에 대한 하나의 이미지에서 exif 정보를 찾았습니다. 전체 출구 정보를 올바르게 표시 할 수 있지만 위도 만 사용하려고하면 항상 null이 표시됩니다. 이것은 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]; 
       } 
      } 
     }]; 
    } 

음,이 시점에서 내가 쉽게 폭에 대한 정보를 취할 수 그리고 이미지의 높이가 있지만 위도 또는 경도를 사용하려고하면 항상 null이 표시됩니다. 내가 뭘 잘못하고있어?

감사합니다.

답변

0

잡을 거리가 있습니다. 애셋 라이브러리에서 반환 된 기본 표현은 이미지의 EXIF ​​데이터와 같은 것을 제거하여 찾을 수 없습니다.

내가 발견 한 것은 수동으로 이미지를 구성하는 바이트를 추출하면 이미지를 재구성 한 다음 EXIF ​​데이터를 얻을 수 있다는 것입니다. 여기

가 바이트를 취득하고있는 NSData 객체로를 반환하는 함수입니다 : 내 경우에는 내가 700K로 이미지의 크기를 제한하는 것을

@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 

주 (나는 다른 체크 코드를했다 귀하의 질문과 관련이없는). 이제

,이 다양한 기준에 맞는 이미지를 자산 라이브러리를 검색 내가 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]; 
    } 
} 

맥 OS X 버전을 EXIFUtility 클래스에서 찾을 수 있습니다

EXIFUtility.h EXIFUtility.m

이 내가 uAlertMe에있는 것과 매우 유사하고 충분한 정보를 제공해야합니다.