CodeMilian
CodeMilian

Reputation: 1290

Unable to load image from asset URL

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

Upvotes: 8

Views: 20064

Answers (5)

Giang
Giang

Reputation: 2729

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)

Upvotes: 0

grimabe
grimabe

Reputation: 641

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)

Upvotes: 8

mwfire
mwfire

Reputation: 1667

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.

Upvotes: 6

Midhun MP
Midhun MP

Reputation: 107131

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];

Upvotes: 14

Mayank Kulshrestha
Mayank Kulshrestha

Reputation: 39

ALAsset *asset = "asset array index"
[tileView.tileImageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];

Upvotes: -1

Related Questions