Can I load a UIImage from a URL?

IosIphoneUiimageUiimagepickercontroller

Ios Problem Overview


I have a URL for an image (got it from UIImagePickerController) but I no longer have the image in memory (the URL was saved from a previous run of the app). Can I reload the UIImage from the URL again?

I see that UIImage has a imageWithContentsOfFile: but I have a URL. Can I use NSData's dataWithContentsOfURL: to read the URL?

EDIT1


based on @Daniel's answer I tried the following code but it doesn't work...

NSLog(@"%s %@", __PRETTY_FUNCTION__, photoURL);		
if (photoURL) {
    NSURL* aURL = [NSURL URLWithString:photoURL];
    NSData* data = [[NSData alloc] initWithContentsOfURL:aURL];
    self.photoImage = [UIImage imageWithData:data];
    [data release];
}

When I ran it the console shows:

-[PhotoBox willMoveToWindow:] file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG
*** -[NSURL length]: unrecognized selector sent to instance 0x536fbe0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL length]: unrecognized selector sent to instance 0x536fbe0'

Looking at the call stack, I'm calling URLWithString, which calls URLWithString:relativeToURL:, then initWithString:relativeToURL:, then _CFStringIsLegalURLString, then CFStringGetLength, then forwarding_prep_0, then forwarding, then -[NSObject doesNotRecognizeSelector].

Any ideas why my NSString (photoURL's address is 0x536fbe0) doesn't respond to length? Why does it say it doesn't respond to -[NSURL length]? Doesn't it know that param is an NSString, not a NSURL?

EDIT2


OK, the only problem with the code is the string to URL conversion. If I hardcode the string, everything else works fine. So something is wrong with my NSString and if I can't figure it out, I guess that should go in as a different question. With this line inserted (I pasted the path from the console log above), it works fine:

photoURL = @"file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG";

Ios Solutions


Solution 1 - Ios

You can do it this way (synchronously, but compact):

UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]];

A much better approach is to use Apple's LazyTableImages to preserve interactivity.

Solution 2 - Ios

You can try SDWebImage, it provides:

  1. Asynchronous loading
  2. Caching for offline use
  3. Place holder image to appear while loading
  4. Works well with UITableView

Quick example:

    [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

Solution 3 - Ios

And the swift version :

   let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
    var err: NSError?
    var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
    var bgImage = UIImage(data:imageData)

Solution 4 - Ios

get DLImageLoader and try folowing code

   [DLImageLoader loadImageFromURL:imageURL
                          completed:^(NSError *error, NSData *imgData) {
                              imageView.image = [UIImage imageWithData:imgData];
                              [imageView setContentMode:UIViewContentModeCenter];
                        
                          }];

Another typical real-world example of using DLImageLoader, which may help someone...

PFObject *aFacebookUser = [self.fbFriends objectAtIndex:thisRow];
NSString *facebookImageURL = [NSString stringWithFormat:
	@"http://graph.facebook.com/%@/picture?type=large",
	[aFacebookUser objectForKey:@"id"] ];

__weak UIImageView *loadMe = self.userSmallAvatarImage;
// ~~note~~ you my, but usually DO NOT, want a weak ref
[DLImageLoader loadImageFromURL:facebookImageURL
   completed:^(NSError *error, NSData *imgData)
	{
	if ( loadMe == nil ) return;
	
	if (error == nil)
		{
		UIImage *image = [UIImage imageWithData:imgData];
		image = [image ourImageScaler];
		loadMe.image = image;
		}
	else
		{
		// an error when loading the image from the net
		}
	}];

As I mention above another great library to consider these days is Haneke (unfortunately it's not as lightweight).

Solution 5 - Ios

If you're really, absolutely positively sure that the NSURL is a file url, i.e. [url isFileURL] is guaranteed to return true in your case, then you can simply use:

[UIImage imageWithContentsOfFile:url.path]

Solution 6 - Ios

Try this code, you can set loading image with it, so the users knows that your app is loading an image from url:

UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading.png"]];
    [yourImageView setContentMode:UIViewContentModeScaleAspectFit];

    //Request image data from the URL:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://yourdomain.com/yourimg.png"]];
    
        dispatch_async(dispatch_get_main_queue(), ^{
            if (imgData)
            {
                //Load the data into an UIImage:
                UIImage *image = [UIImage imageWithData:imgData];
            
                //Check if your image loaded successfully:
                if (image)
                {
                    yourImageView.image = image;
                }
                else
                {
                    //Failed to load the data into an UIImage:
                    yourImageView.image = [UIImage imageNamed:@"no-data-image.png"];
                }
            }
            else
            {
                //Failed to get the image data:
                yourImageView.image = [UIImage imageNamed:@"no-data-image.png"];
            }
        });
    });

Solution 7 - Ios

Check out the AsyncImageView provided over here. Some good example code, and might even be usable right "out of the box" for you.

Solution 8 - Ios

AFNetworking provides async image loading into a UIImageView with placeholder support. It also supports async networking for working with APIs in general.

Solution 9 - Ios

Make sure enable this settings from iOS 9:

App Transport Security Settings in Info.plist to ensure loading image from URL so that it will allow download image and set it.

enter image description here

And write this code:

NSURL *url = [[NSURL alloc]initWithString:@"http://feelgrafix.com/data/images/images-1.jpg"];
NSData *data =[NSData dataWithContentsOfURL:url];
quickViewImage.image = [UIImage imageWithData:data];

Solution 10 - Ios

The way using a Swift Extension to UIImageView (source code here):

##Creating Computed Property for Associated UIActivityIndicatorView ##

import Foundation
import UIKit
import ObjectiveC
 
private var activityIndicatorAssociationKey: UInt8 = 0
 
extension UIImageView {
    //Associated Object as Computed Property
    var activityIndicator: UIActivityIndicatorView! {
        get {
            return objc_getAssociatedObject(self, &activityIndicatorAssociationKey) as? UIActivityIndicatorView
        }
        set(newValue) {
            objc_setAssociatedObject(self, &activityIndicatorAssociationKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }
    
    private func ensureActivityIndicatorIsAnimating() {
        if (self.activityIndicator == nil) {
            self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
            self.activityIndicator.hidesWhenStopped = true
            let size = self.frame.size;
            self.activityIndicator.center = CGPoint(x: size.width/2, y: size.height/2);
            NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                self.addSubview(self.activityIndicator)
                self.activityIndicator.startAnimating()
            })
        }
    }
    

##Custom Initializer and Setter ##

    convenience init(URL: NSURL, errorImage: UIImage? = nil) {
        self.init()
        self.setImageFromURL(URL)
    }
    
    func setImageFromURL(URL: NSURL, errorImage: UIImage? = nil) {
        self.ensureActivityIndicatorIsAnimating()
        let downloadTask = NSURLSession.sharedSession().dataTaskWithURL(URL) {(data, response, error) in
            if (error == nil) {
                NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                    self.activityIndicator.stopAnimating()
                    self.image = UIImage(data: data)
                })
            }
            else {
                self.image = errorImage
            }
        }
        downloadTask.resume()
    }
}

Solution 11 - Ios

Local URL's are super simple, just use this :

UIImage(contentsOfFile: url.path)

Solution 12 - Ios

The Best and easy way to load Image via Url is by this Code:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSData *data =[NSData dataWithContentsOfURL:[NSURL URLWithString:imgUrl]];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        imgView.image= [UIImage imageWithData:data];
    });
});

Replace imgUrl by your ImageURL
Replace imgView by your UIImageView.

It will load the Image in another Thread, so It will not slow down your App load.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionprogrmrView Question on Stackoverflow
Solution 1 - IosDaniel BlezekView Answer on Stackoverflow
Solution 2 - IosMuhammad Hassan NasrView Answer on Stackoverflow
Solution 3 - Iosuser3763002View Answer on Stackoverflow
Solution 4 - IosMuruganandham KView Answer on Stackoverflow
Solution 5 - IosDhiraj GuptaView Answer on Stackoverflow
Solution 6 - IosJouharView Answer on Stackoverflow
Solution 7 - IosmarccView Answer on Stackoverflow
Solution 8 - IospauliephonicView Answer on Stackoverflow
Solution 9 - IosNagarjunView Answer on Stackoverflow
Solution 10 - Iosfpg1503View Answer on Stackoverflow
Solution 11 - IosPeter SuwaraView Answer on Stackoverflow
Solution 12 - IosjalmatariView Answer on Stackoverflow