How to Set The Image Name When Saving to The Camera Roll

In principle, you can’t. But in practice, there is a way… Read on to find out.

iOS names the image IMG_<num> to avoid file name clashes. There is no way to change that from your app.
However, if the user later imports an image to iPhoto, then the metadata of the image will determine its title, description, and keywords.
If the user then exports the image to file, iPhoto can use the title for the name of the exported file. (Instructions for doing that are down below, after the code.)

Here is the code to set the metadata and save the image to the camera roll. The code below gets the image from the camera, but this isn’t necessary – the image can come from anywhere.

#import 
#import 

- (void) imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info
{
    [self dismissViewControllerAnimated:YES completion:nil];
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    NSMutableDictionary *metadata = info[UIImagePickerControllerMediaMetadata];

    // set image name and keywords in IPTC metadata
    NSString *iptcKey = (NSString *)kCGImagePropertyIPTCDictionary;
    NSMutableDictionary *iptcMetadata = metadata[iptcKey];
    iptcMetadata[(NSString *)kCGImagePropertyIPTCObjectName] = @"Image Title";
    iptcMetadata[(NSString *)kCGImagePropertyIPTCKeywords] = @"some keywords";
    metadata[iptcKey] = iptcMetadata;

    // set image description in TIFF metadata
    NSString *tiffKey = (NSString *)kCGImagePropertyTIFFDictionary;
    NSMutableDictionary *tiffMetadata = metadata[tiffKey];
    tiffMetadata[(NSString *)kCGImagePropertyTIFFImageDescription] = @"Description for image"; // only visible in iPhoto when IPTCObjectName is set
    metadata[tiffKey] = tiffMetadata;

    // save image to camera roll
    ALAssetsLibrary library = [[ALAssetsLibrary alloc] init];
    [library writeImageToSavedPhotosAlbum:image.CGImage metadata:metadata completionBlock:nil];
}

Now the user can import the images to iPhoto and get your programmed title, description, and keywords.

To export the images to files that have the same name as the image title, the user should choose File > Export and then change the File Name field to Use title.

export

9 thoughts on “How to Set The Image Name When Saving to The Camera Roll

  1. I want to save my picture to the camera roll and dont mind the “IMG_0000” namimg convention but is there a way to get the name it has saved it as in your code and put it in a string?

  2. When you save the image to album, you get its asset URL in your completion block. You can use this URL to find the file name.

    For example:

    [[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:capturedImage.CGImage metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) {
        NSLog(@"image file name: %@", assetURL.lastPathComponent);
    }];
    
  3. I have tried this but the file name is garbage I need it to return the name of the jpg (EG IMG_xxxx.jpg) Please help spent weeks on this one issue

    Mark

  4. my app is a data collection app. its saves all the information collected Including a photo of the asset and saves it to a text file. if you are collecting 100’s of items and photos i need to know which photo goes with each set of data collected

    I can’t understand why tis is so hard please help

    Mark

  5. Just use the asset URL, it will allow you to retrieve the photo from the ALAssetsLibrary and show it to the user.

  6. Hi

    I need the filename as 100% of my user base is PC based. I need to be able to get the photos off the iPhone using a cable to a pc therefore the photos need to be in DCIM which is the only folder you can see on a PC

    The data file is a csv file that people load into excel and it gives a spreadsheet of all the assets data collected along with a reference to the photo if i use the asset URL how will a PC user know which photo is for which data. This data is then use for reports and data analysis so can’t be done on th phone.

    I have the following code which gets close it saves the picture then uses the photo framework to put the last saved photo file path in the string pathname

    UIImageWriteToSavedPhotosAlbum(chosenImage, nil,nil, nil);

    [picker dismissViewControllerAnimated:YES completion:NULL];
    PHAsset *asset = chosenImage;
    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
    fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@”creationDate” ascending:YES]];
    PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
    if (fetchResult != nil && fetchResult.count > 0) {
    // get last photo from Photos
    asset = [fetchResult lastObject];
    }

    if (asset) {
    // get photo info from this asset
    PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
    imageRequestOptions.synchronous = YES;
    [[PHImageManager defaultManager]
    requestImageDataForAsset:asset
    options:imageRequestOptions
    resultHandler:^(NSData *imageData, NSString *dataUTI,
    UIImageOrientation orientation,
    NSDictionary *info)
    {
    NSLog(@”info = %@”, info);
    if ([info objectForKey:@”PHImageFileURLKey”]) {
    // path looks like this –
    // file:///var/mobile/Media/DCIM/###APPLE/IMG_####.JPG
    NSURL *path = [info objectForKey:@”PHImageFileURLKey”];
    NSString *pathname = [path absoluteString];
    filenm.text = pathname;

    }
    }];
    }

    This gives the full path and filename exactly how i want except one crucial thing. it is for the photo taken BEFORE the photo I have just taken. If I take another picture it gives the right filename

    The point being I know its possible just can see how.

    I write for android and windows and its a one line pice of code there can’t understand why this is so difficult in IOS

    Please help I have been stuck on this for weeks

    Mark

  7. Interesting. In that case, maybe you just need to wait until the photo frameworks updates its own list of photos. I.e., move everything after the first two lines into a delayed block:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    // the rest of your code goes here
    });

  8. Yonat

    Thanks a ton that worked a treat

    had to change the 0.1` to 1 though as it takes a second to update

    Now I have the correct file-name for the data

    Thank You

    Mark

Leave a Reply