0

I am trying to save GPS data along with EXIF data for a photo taken in iphone. I went through below SO question and was able to tag GPS data with a photo.

LINK: SOURCE

When i click on selectPhoto button, the photo is duplicating inside cameraroll. Below is my complete code.

- (IBAction)takePhoto:(id)sender {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = UIImagePickerControllerSourceTypeCamera;

    [self presentViewController:picker animated:YES completion:NULL];
}

- (IBAction)selectPhoto:(id)sender {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.allowsEditing = YES;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    [self presentViewController:picker animated:YES completion:NULL];
}

#pragma mark - Image Picker Controller delegate methods

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

   UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
   self.imageView.image = image;

   NSLog(@"image %@\ninfo: %@",image, info);
   [picker dismissViewControllerAnimated:YES completion:NULL];

   [self saveImage:image withInfo:info];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

    [picker dismissViewControllerAnimated:YES completion:NULL];

}

- (void) saveImage:(UIImage *)imageToSave withInfo:(NSDictionary *)info
{
    // Get the image metadata (EXIF & TIFF)
    NSMutableDictionary * imageMetadata = [[info objectForKey:UIImagePickerControllerMediaMetadata] mutableCopy];

    // add (fake) GPS data
    double latitude = locationManager.location.coordinate.latitude;
    double longitude = locationManager.location.coordinate.longitude;

    CLLocationCoordinate2D coordSF = CLLocationCoordinate2DMake(latitude ,longitude);

    // arbitrary altitude and accuracy
    double altitudeSF = 0.0;
    double accuracyHorizontal = 0.0;
    double accuracyVertical = 0.0;
    NSDate * nowDate = [NSDate date];

    // create CLLocation for image
    CLLocation * loc = [[CLLocation alloc] initWithCoordinate:coordSF altitude:altitudeSF horizontalAccuracy:accuracyHorizontal verticalAccuracy:accuracyVertical timestamp:nowDate];

    // this is in case we try to acquire actual location instead of faking it with the code right above
    if ( loc ) {
        [imageMetadata setObject:[self gpsDictionaryForLocation:loc] forKey:(NSString*)kCGImagePropertyGPSDictionary];
    }

    // Get the assets library
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

    // create a completion block for when we process the image
    ALAssetsLibraryWriteImageCompletionBlock imageWriteCompletionBlock =
    ^(NSURL *newURL, NSError *error) {
        if (error) {
            NSLog( @"Error writing image with metadata to Photo Library: %@", error );
        } else {
          NSLog( @"Wrote image %@ with metadata %@ to Photo Library",newURL,imageMetadata);
          //  NSLog( @"Wrote image with metadata to Photo Library");
        }
    };

    // Save the new image to the Camera Roll, using the completion block defined just above
    [library writeImageToSavedPhotosAlbum:[imageToSave CGImage]
                                 metadata:imageMetadata
                          completionBlock:imageWriteCompletionBlock];
}

/**
 A convenience method to generate the {GPS} portion of a photo's EXIF data from a CLLLocation.

 @param location the location to base the NSDictionary on

 @return NSDictionary containing {GPS} block for a photo's EXIF data
 */
- (NSDictionary *) gpsDictionaryForLocation:(CLLocation *)location
{
    CLLocationDegrees exifLatitude  = location.coordinate.latitude;
    CLLocationDegrees exifLongitude = location.coordinate.longitude;

    NSString * latRef;
    NSString * longRef;
    if (exifLatitude < 0.0) {
        exifLatitude = exifLatitude * -1.0f;
        latRef = @"S";
    } else {
        latRef = @"N";
    }

    if (exifLongitude < 0.0) {
        exifLongitude = exifLongitude * -1.0f;
        longRef = @"W";
    } else {
        longRef = @"E";
    }

    NSMutableDictionary *locDict = [[NSMutableDictionary alloc] init];

    // requires ImageIO
    [locDict setObject:location.timestamp forKey:(NSString*)kCGImagePropertyGPSTimeStamp];
    [locDict setObject:latRef forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
    [locDict setObject:[NSNumber numberWithFloat:exifLatitude] forKey:(NSString *)kCGImagePropertyGPSLatitude];
    [locDict setObject:longRef forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
    [locDict setObject:[NSNumber numberWithFloat:exifLongitude] forKey:(NSString *)kCGImagePropertyGPSLongitude];
    [locDict setObject:[NSNumber numberWithFloat:location.horizontalAccuracy] forKey:(NSString*)kCGImagePropertyGPSDOP];
    [locDict setObject:[NSNumber numberWithFloat:location.altitude] forKey:(NSString*)kCGImagePropertyGPSAltitude];

    NSLog(@" locDict %@", locDict);
    return locDict;

}
Community
  • 1
  • 1
  • you could simply remove old image before saving the new one. URL can be retrieved using `info[UIImagePickerControllerMediaURL]` – kambala Jul 12 '14 at 10:41

1 Answers1

0

IN this method you used this line

- (void) saveImage:(UIImage *)imageToSave withInfo:(NSDictionary *)info

PLEASE remove below line

  [library writeImageToSavedPhotosAlbum:[imageToSave CGImage]
                             metadata:imageMetadata
                      completionBlock:imageWriteCompletionBlock];

and try this . Thanks

Jogendra.Com
  • 6,394
  • 2
  • 28
  • 35