How do I get a thumbnail or saveable path from UIImagePickerController to use for a UIImageView?

viperacr99 picture viperacr99 · Jan 11, 2011 · Viewed 12.6k times · Source

Could somebody please explain or show some sample code of how I can use get a thumbnail to be put into a UIImageView after the user selects a photo with UIImagePickerController?

Let's say I want to set a thumbnail as the image of a table view cell. When the user presses the cell, the image picker is shown and the user selects an image that is already on their device. I also want to save the path to that thumbnail so that the next time the view is displayed, the proper thumbnail can be shown.

I am able to display an image picker and my delegate get's the chosen image correctly, but I want the path to the thumbnail, and I want to load the thumbnail using that path (i.e. I want to save the path). I've searched for hours today and haven't figured this out. Perhaps I'm not understanding ALAsset, or maybe it is something else, but I can't find any examples that are helping me. I have never used the image picker or ALAsset before now, so I'm completely new at this.

Answer

Walter picture Walter · Jan 12, 2011

//If you are reading this and look at the comments below and think ??WTF?? it is because I am editing my original Answer instead of posting two Answers in hopes that things will be cleaner. It is important to know that ALAssetsLibrary is an iOS 4.x thing.

The code below will function to take an asset-library URL and then make a UIImage out of the thumbnail representation. Though I use the asset-library url directly there is no reason that this same code couldn't begin by transforming a string representation into a NSURL in order to satisfy the imageURL assignment. Disclaimer: this code probably leaks or something worse, but it answers the original poster's question and is hopefully of value.

The code below is borrowing heavily on this Stack Overflow question that covers basically this same topic. In addition to the code here, I have included AssetsLibrary.framework and the ALAssetsLibrary typedefs referenced in the other question.

The whole trick is that you cannot reference the NSURL from an asset-library directly. I think (though I don't know) that it is somehow referencing a data store instead of a file so the data returned from the URL isn't straight NSData so you cannot use it the old way.

There is a UIImageView in the code that is called photo. Hopefully everything else is easy to figure out.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    NSLog(@"%@",imageURL);
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        CGImageRef iref = [myasset thumbnail];
        if (iref) {
            UIImage *theThumbnail = [UIImage imageWithCGImage:iref];
            [[self photo] setImage:theThumbnail];

        }
    };


    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        NSLog(@"booya, cant get image - %@",[myerror localizedDescription]);
    };

    if(imageURL)
    {
        ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
        [assetslibrary assetForURL:imageURL 
                       resultBlock:resultblock
                      failureBlock:failureblock];
    }

    [self dismissModalViewControllerAnimated:YES];
}

If you don't want the thumbnail but do want the full photo, you will just change the code in the AssetForURLResult block to something like this:

       ALAssetRepresentation *rep = [myasset defaultRepresentation];
    CGImageRef iref = [rep fullResolutionImage];

We can leave that exercize for the user.

Good luck, hope this helps clear things up for you.