8

I have a class that stores information about the assets on the phone (images, videos).

My class has the ResourceURLString defined as such

@property NSURL *ResourceURL;

I am setting the property while looping trough the assets on the phone as such

Item.ResourceURLString = [[asset valueForProperty:ALAssetPropertyURLs] objectForKey:[[asset valueForProperty:ALAssetPropertyRepresentations] objectAtIndex:0]];

When the user clicks on an image I want to load the image.

The code that I have is this

NSData *imageUrl = [NSData dataWithContentsOfURL:[NSURL URLWithString:[CurrentItem.ResourceURL absoluteString]]];    

Img = [UIImage imageWithData:imageUrl];

But the Image is always nil I have verified that the ResourceURL property contains the URL assets: library://asset/asset.JPG?id=82690321-91C1-4650-8348-F3FD93D14613&ext=JPG

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
CodeMilian
  • 1,262
  • 2
  • 17
  • 41

5 Answers5

14

You can't load images in this way.

You need to use ALAssetsLibrary class for this.

Add assetslibrary framework to your project and add header files.

Use the below code for loading image:

ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
    ALAssetRepresentation *rep = [myasset defaultRepresentation];
    CGImageRef iref = [rep fullResolutionImage];
    if (iref) {
        UIImage *largeimage = [UIImage imageWithCGImage:iref];
        yourImageView.image = largeImage;
    }
};

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

NSURL *asseturl = [NSURL URLWithString:yourURL];
ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
[assetslibrary assetForURL:asseturl 
                   resultBlock:resultblock
                  failureBlock:failureblock];
Natan R.
  • 5,141
  • 1
  • 31
  • 48
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • I have followed you code and What If I want to add Image URL to this line of code [_pinterest createPinWithImageURL:[NSURL URLWithString:@"??"]; What URLString Should I right there to get an Image in pinterest? – MayurCM Jan 05 '14 at 13:47
  • @MayurCM: `yourURL` represents the asset url, it'll look something like: `library://asset/asset.JPG?id=82690321-91C1-4650-8348-F3FD93D14613&ext=JPG`. You can't use web url here. Asset library is used to load the image from photolibrary not from the web or bundle. – Midhun MP Jan 06 '14 at 04:36
  • But When I pass assetsLibrary then also I'm unable to pin image on pinterest. – MayurCM Jan 06 '14 at 04:46
  • `assetForURL` is an asynchronous method. you could not get the result immediately. – Xiao Mar 27 '14 at 11:32
8

Since iOS 8 you can use the Photos Framework here is how to do it in Swift 3

import Photos // use the Photos Framework

// declare your asset url
let assetUrl = URL(string: "assets-library://asset/asset.JPG?id=9F983DBA-EC35-42B8-8773-B597CF782EDD&ext=JPG")!

// retrieve the list of matching results for your asset url
let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [assetUrl], options: nil)


if let photo = fetchResult.firstObject {

    // retrieve the image for the first result
    PHImageManager.default().requestImage(for: photo, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFill, options: nil) {
        image, info in

        let myImage = image //here is the image
    }
}

Use PHImageManagerMaximumSize if you want to retrieve the original size of the picture. But if you want to retrieve a smaller or specific size you can replace PHImageManagerMaximumSize by CGSize(width:150, height:150)

grimabe
  • 611
  • 1
  • 7
  • 5
6

As of iOS 9.0 ALAssetsLibraryis deprecated. Since iOS 8.0, this works with the PHPhotoLibrary. This is a small UIImage extension, Swift 2X. This uses a fixed image size.

import Photos

extension UIImageView {

    func imageFromAssetURL(assetURL: NSURL) {

        let asset = PHAsset.fetchAssetsWithALAssetURLs([assetURL], options: nil)

        guard let result = asset.firstObject where result is PHAsset else {
           return
        }

        let imageManager = PHImageManager.defaultManager()

        imageManager.requestImageForAsset(result as! PHAsset, targetSize: CGSize(width: 200, height: 200), contentMode: PHImageContentMode.AspectFill, options: nil) { (image, dict) -> Void in
            if let image = image {
                self.image = image
            }
        }
    }
}

Getting the imageReferenceURL from the UIImagePickerController delegate:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    imageURL = info[UIImagePickerControllerReferenceURL] as? NSURL
}

Setting the image

let imageView = UIImageView()
imageView.imageFromAssetURL(imageURL)

There might be effects I haven't encountered yet, a classic would be UITableViewCell or thread problems. I'll keep this updated, also appreciate your feedback.

mwfire
  • 1,657
  • 13
  • 21
0

For Swift 5

fetchAssets(withALAssetURLs) will be removed in a future release. Hence we using fetchAssets to get image from asset local identifier

extension UIImageView {
func imageFromLocalIdentifier(localIdentifier: String, targetSize: CGSize) {
        let fetchOptions = PHFetchOptions()
        // sort by date desending
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        // fetch photo with localIdentifier
        let results = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: fetchOptions)
        let manager = PHImageManager.default()
        results.enumerateObjects { (thisAsset, _, _) in
            manager.requestImage(for: thisAsset, targetSize: targetSize, contentMode: .aspectFit, options: nil, resultHandler: {(image, _) in
                DispatchQueue.main.async {[weak self] in
                    self?.image = image
                }
            })
        }
    }
}

Update

let image = UIImage(data: NSData(contentsOf: imageURL as URL)! as Data)
Giang
  • 2,384
  • 2
  • 25
  • 26
  • how to use this function? Dunno what localIdentifier mean – famfamfam Apr 01 '21 at 09:27
  • @famfamfam: `localIdentifier` in properties of `PHAsset` . You can have `PHAsset` to request image. I will update more detail – Giang Apr 01 '21 at 09:37
  • i have localIdentifer, how can i using it to condition to fetch. image? – famfamfam Apr 12 '21 at 06:09
  • 1
    @famfamfam: hi, when you got `localIdentifier` this's detect what's image you want. First fetch request all images from photo library, by using -> let fetchOptions = PHFetchOptions() // sort by date desending fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] // fetch all photos let results: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions).Second you will find in results image with `localIdentifier` you got. – Giang Apr 12 '21 at 10:30
  • yeah, i know it, but i think if my gallery have about 10000 photo, does it make delay when fetchAssets? – famfamfam Apr 12 '21 at 13:11
  • @famfamfam hi dont worry you can request exact image with `localIdentifier` by this. let results = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: fetchOptions) let manager = PHImageManager.default() results.enumerateObjects { (thisAsset, _, _) in manager.requestImage(for: thisAsset, targetSize: targetSize, contentMode: .aspectFit, options: nil, resultHandler: {(image, _) in // got image }) } – Giang Apr 12 '21 at 19:58
  • 1
    I just updated new answer to more clearly – Giang Apr 12 '21 at 20:19
-1
ALAsset *asset = "asset array index"
[tileView.tileImageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
Midhun MP
  • 103,496
  • 31
  • 153
  • 200