8

The weirdest thing is happening. I have an action sheet which gives the user the choice to either take a photo with the camera or choose one from the camera roll. Upon the UIImagePicker returning from selection I use the ALAssetsLibrary to determine the GPS information embedded in the photo. Choosing a photo from the camera roll works perfectly and I am able to retrieve the GPS information. However, taking a photo with the camera provides absolutely no GPS information, in fact I have no metadata at all. Does anyone know what I'm doing wrong here?

Code below:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{    
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    if([mediaType isEqualToString:(__bridge NSString *)kUTTypeImage])
    {        
        void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset)
        {
            // get images metadata
            NSDictionary *metadata = asset.defaultRepresentation.metadata;
            NSLog(@"Image Meta Data: %@",metadata);

            // get coords 
            CLLocation *location = [asset valueForProperty:ALAssetPropertyLocation];
            NSLog(@"coordLat: %f , coordLon: %f", location.coordinate.latitude, location.coordinate.longitude);

            // do more here - rest of code snipped to keep this question short

    };
    NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library assetForURL:assetURL
             resultBlock:ALAssetsLibraryAssetForURLResultBlock
            failureBlock:^(NSError *error) 
            {
                // handle error 
            }];

    // rest of code snipped to keep this question short

As I explained, the following is outputted when using the camera.

2012-04-15 17:58:28.032 MyApp[511:707] Image Meta Data: (null)
2012-04-15 17:58:28.041 MyApp[511:707] coordLat: 0.000000 , coordLon: 0.000000

However, if I choose an existing photo, or exit out of the app, take a new photo with the camera, then go back into the app and select that photo from the camera roll i get the following output from NSLog.

2012-04-15 17:57:03.286 MyApp[511:707] Image Meta Data: {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
Depth = 8;
Orientation = 6;
PixelHeight = 1936;
PixelWidth = 2592;
"{Exif}" =     {
    ApertureValue = "2.970854";
    BrightnessValue = "2.886456";
    ColorSpace = 1;
    ComponentsConfiguration =         (
        1,
        2,
        3,
        0
    );
    DateTimeDigitized = "2012:04:15 17:24:02";
    DateTimeOriginal = "2012:04:15 17:24:02";
    ExifVersion =         (
        2,
        2,
        1
    );
    ExposureMode = 0;
    ExposureProgram = 2;
    ExposureTime = "0.06666667";
    FNumber = "2.8";
    Flash = 24;
    FlashPixVersion =         (
        1,
        0
    );
    FocalLength = "3.85";
    ISOSpeedRatings =         (
        80
    );
    MeteringMode = 5;
    PixelXDimension = 2592;
    PixelYDimension = 1936;
    SceneCaptureType = 0;
    SensingMethod = 2;
    Sharpness = 2;
    ShutterSpeedValue = "3.9112";
    SubjectArea =         (
        1295,
        967,
        699,
        696
    );
    WhiteBalance = 0;
};
"{GPS}" =     {
    Altitude = "14.9281";
    AltitudeRef = 0;
    ImgDirection = "107.4554";
    ImgDirectionRef = T;
    Latitude = "32.7366666666667";
    LatitudeRef = N;
    Longitude = "71.679";
    LongitudeRef = W;
    TimeStamp = "21:26:20.00";
};
"{TIFF}" =     {
    DateTime = "2012:04:15 17:24:02";
    Make = Apple;
    Model = "iPhone 4";
    Orientation = 6;
    ResolutionUnit = 2;
    Software = "5.0.1";
    XResolution = 72;
    YResolution = 72;
    "_YCbCrPositioning" = 1;
};
}
2012-04-15 17:57:03.302 MyApp[511:707] coordLat: 32.7366666666667 , coordLon: -71.679

PS - I'm using xCode 4.3 w/ ARC

ElasticThoughts
  • 3,417
  • 8
  • 43
  • 58
  • A couple of answers that actually work are available [here](http://stackoverflow.com/questions/9766394/get-exif-data-from-uiimage-uiimagepickercontroller) – GreyHands Apr 15 '12 at 22:27
  • I've followed those examples and I'm still hiving the same issue. Would you be able to post some code for me if you know specifically what my issue is? Thanks in advance. – ElasticThoughts Apr 16 '12 at 11:18
  • 1
    Did you turn on location services location services as the poster of accepted answer suggests? It looks that in some cases you have to add location meta data yourself. Which shouldn't be a problem if you have location services turned on. – Rok Jarc Apr 16 '12 at 12:02
  • Yes, location services is on and I can pull the lat/lon info from CLLocaionManager if I have too Its just weird that `asset.defaultRepresentation.metadata` returns absolutely no metadata when using the camera but using the EXACT same code on an image chosen from the camera roll does return metadata. I guess that until I figure this out I'll have to use the CLLocation information. Thanks again! – ElasticThoughts Apr 16 '12 at 13:01
  • Did you ever get this solved? My question is pretty much the same as yours (so if you have an answer, you can claim the bounty...) http://stackoverflow.com/questions/10302250/reading-the-gps-data-from-the-image-returned-by-the-camera-in-ios-iphone – Paul Cezanne May 03 '12 at 15:11
  • Not exactly, I have two work arounds, both of which are not acceptable to you after reading your post. 1) save the photo to the camera roll, then pull it off and grab the GPS info from the metadata. I feel this is a major hack so I did not choose this method. 2) Start core location first, then launch the camera, after the image is taken use the coords returned from locationManager:didUpdateToLocation:fromLocation. Neither options is ideal, if you get an answer on this please let me know. I'll keep checking your post, it seems that you've gotten a lot of views and responses thus far... – ElasticThoughts May 03 '12 at 19:04
  • 1
    What about using the `NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];` in `didFinish...` in place of `NSDictionary *metadata = asset.defaultRepresentation.metadata;`? Give one try to it :) – The iOSDev Aug 27 '12 at 06:38

2 Answers2

13

In - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

Try this when saving the Photo

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library writeImageToSavedPhotosAlbum:image.CGImage
                                 metadata:[info objectForKey:UIImagePickerControllerMediaMetadata]
                          completionBlock:^(NSURL *assetURL, NSError *error) {
        NSLog(@"assetURL %@", assetURL);
    }];
KONG
  • 7,271
  • 6
  • 28
  • 27
  • This should be marked as the correct solution. Save a photo taken from the camera to the camera roll and then you can use that as your assetURL to get ALAsset metadata! – Albert Renshaw Dec 12 '13 at 22:41
  • 1
    ^Not really. While you will get the ALAsset from the assetURL in the completion block, valueForProperty:ALAssetPropertyLocation will return nil. The only real solution to this seems to be to use Core Location in the app. – Matthew Quiros May 08 '14 at 16:26
0

@Thanh-Cong Vo is right about how to save the image to Photo Album. And See what say the Apples documents about saving image to photo album

To save a still image to the user’s Camera Roll album, call the UIImageWriteToSavedPhotosAlbum function from within the body of the imagePickerController:didFinishPickingMediaWithInfo: method. To save a movie to the user’s Camera Roll album, instead call the UISaveVideoAtPathToSavedPhotosAlbum function. These functions, described in UIKit Function Reference, save the image or movie only; they do not save metadata.

Starting in iOS 4.0, you can save still-image metadata, along with a still image, to the Camera Roll. To do this, use the writeImageToSavedPhotosAlbum:metadata:completionBlock: method of the Assets Library framework. See the description for the UIImagePickerControllerMediaMetadata key.

The iOSDev
  • 5,237
  • 7
  • 41
  • 78