Question

I'm trying to create a custom image gallery within my iOS app. I would like to enable the user to be able to save certain meta data with the image so that it can be pulled up in the app later with the attached information.

First, when the user takes a picture, the app saves the image into a custom album for the app:

UITextField *nameField = [alertView textFieldAtIndex:0];

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

[metaData setObject:currentEvent forKey:kMetaDataEventKey];
[metaData setObject:[AppDelegate getActivePerson].name forKey:kMetaDataPersonKey];
[metaData setObject:nameField.text forKey:kMetaDataNameKey];
NSLog(@"Saving image with metadata: %@", metaData);

NSMutableDictionary *realMetaData = [[NSMutableDictionary alloc] init];
[realMetaData setObject:metaData forKey:kCGImagePropertyTIFFDictionary];
[library saveImage:imageToSave toAlbum:albumName metadata:realMetaData withCompletionBlock:^(NSError *error) {
    if ( error != nil )
    {
        NSLog(@"Error saving picture? %@", error);
    }
    [self.tableView reloadData];
}];

Upon saving I get the following log message:

Saving image with metadata: {
    Event = t;
    Person = "George James";
    PictureName = tt;
}

Then when I attempt to retrieve the images later, I use this function

-(void) loadAssets
{
    self.assets = [NSMutableArray arrayWithCapacity:album.numberOfAssets];
    [album enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if ( result != nil )
        {
            NSDictionary *metaData = result.defaultRepresentation.metadata;
            NSLog(@"Retrieved image metadata: %@", metaData);
        }
        else
        {
            [self.tableView reloadData];
        }
    }];
}

But the log indicates that it did not successfully save the meta data associated with the image:

Retrieved image metadata: {
    ColorModel = RGB;
    DPIHeight = 72;
    DPIWidth = 72;
    Depth = 8;
    Orientation = 1;
    PixelHeight = 720;
    PixelWidth = 960;
    "{Exif}" =     {
        ColorSpace = 1;
        ComponentsConfiguration =         (
            1,
            2,
            3,
            0
        );
        ExifVersion =         (
            2,
            2,
            1
        );
        FlashPixVersion =         (
            1,
            0
        );
        PixelXDimension = 960;
        PixelYDimension = 720;
        SceneCaptureType = 0;
    };
    "{TIFF}" =     {
        Orientation = 1;
        ResolutionUnit = 2;
        XResolution = 72;
        YResolution = 72;
        "_YCbCrPositioning" = 1;
    };
}

library is an ALAssetsLibrary instance, and the saveImage: toAlbum: method is from this blog post, only slightly modified so that I can save metadata as such:

-(void)saveImage:(UIImage *)image toAlbum:(NSString *)albumName metadata:(NSDictionary *)metadata withCompletionBlock:(SaveImageCompletion)completionBlock
{
    //write the image data to the assets library (camera roll)
    [self writeImageToSavedPhotosAlbum:image.CGImage
                              metadata:metadata
                       completionBlock:^(NSURL* assetURL, NSError* error) {

                           //error handling
                           if (error!=nil) {
                               completionBlock(error);
                               return;
                           }

                           //add the asset to the custom photo album
                           [self addAssetURL: assetURL
                                     toAlbum:albumName
                         withCompletionBlock:completionBlock];

                       }
     ];

}

The image is coming from a UIImagePickerController that uses the camera. The picture is successfully being saved to the correct album, just missing the metadata.

Am I doing something wrong in the save/load process? Am I actually not allowed to save custom meta data to an image?

Was it helpful?

Solution

I did some testing, and from what I can tell, the short answer is 'you can't do that.' It looks like the metadata has to conform to specific EXIF Metadata keys. You could look up the available TIFF Metadata keys and see if there are any values you want to set/overwrite. You could try, for example, using kCGImagePropertyTIFFImageDescription to store your data.

NSMutableDictionary *tiffDictionary= [[NSMutableDictionary alloc] init];
NSMutableDictionary *myMetadata = [[NSMutableDictionary alloc] init];
[tiffDictionary setObject:@"My Metadata" forKey:(NSString*)kCGImagePropertyTIFFImageDescription];
[myMetadata setObject:tiffDictionary forKey:(NSString*)kCGImagePropertyTIFFDictionary];

... and save myMetadata with the image.

For other keys, see this: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGImageProperties_Reference/Reference/reference.html

Otherwise, what I would do is create an NSDictionary that uses an image's unique identifier as a key, and store the metadata object as the value. Save/Load this NSDictionary whenever you save/load an image.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top