开发者

iPhone: How to get a UIImage from a url?

How 开发者_开发知识库do you download an image and turn it into a UIImage?


NSURL *url = [NSURL URLWithString:@"http://example.com/image.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];

However, this isn't asynchronous.


You should keep in mind that loading the image data with the sample code you've provided in your own answer will block the main thread until the download has completed. This is a useability no-no. The users of your app will think your app is unresponsive. If you want to download an image, prefer NSURLConnection to download it asynchronously in its own thread.

Read the Apple documentation about async downloads with NSURLConnection.

When your download completes, you can then instantiate your UIImage from the data object:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (requestData)
    {
        self.image = [[[UIImage alloc] initWithData:requestData] autorelease];
    }
}

Where requestData and image are instance variables of your containing class, and image is a retained property. Be sure to release image in the dealloc routine of the class, e.g. using self.image=nil;.


It is true that Asynchronous loading is a must, but you can also achieve that with a background call if you just need a simple solution.

[self performSelectorInBackground:@selector(loadImage) withObject:nil];

- (void)loadImage
{
   NSURL * url = [NSURL URLWithString:@"http://.../....jpg"];
   NSData * data = [NSData dataWithContentsOfURL:url];
   UIImage * image = [UIImage imageWithData:data];
   if (image)
   {
       // Success use the image
       ...
   }
   else
   {
       // Failed (load an error image?)
       ...
   }
}   


You can load an image in a UIImageView from a URL without blocking the UI thread simply using the dispatch_async:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSURL *url = [NSURL URLWithString:myURL];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage* image = [[UIImage alloc]initWithData:data];

            dispatch_async(dispatch_get_main_queue(), ^{
                [myImageView setImage:image];
            });
        });

The first dispatch_async is used to load the image from the URL in background (without blocking the UI). The second dispatch_async is used to actually inject the image just loaded in the UIImageView. Please, note that the second dispatch_async is designed to work on the main thread (the UI thread) that is, indeed, the thread used to update the UI.


There is a really good example here using blocks: http://ios-blog.co.uk/iphone-development-tutorials/uiimage-from-url-%E2%80%93-simplified-using-blocks/


Based on @philfreo's answer I created a NSURL Extension in swift using BrightFutures (for the asynchronous callback:

extension NSURL{
    func downloadImage() -> Future<UIImage, NSError>{

        let promise = Promise<UIImage, NSError>()

        Queue.global.async{
            if let data = NSData(contentsOfURL: self){
                if let image = UIImage(data: data){
                    promise.success(image)
                    return
                }
            }
            promise.failure(NSError())
        }

        return promise.future
    }
}

This then lets me do:

import BrightFutures

let someURL = ...;
someURL.downloadImage().onSuccess{ image in
  // Do something with the UIImage
}

Update

A simple synchronous extension could look like this:

extension NSURL{
    func downloadImage() -> UIImage?{
        if let data = NSData(contentsOfURL: self){
            return UIImage(data: data){
        }
    return nil
    }
}


This is what @philfreo's answer looks like in swift:

let urlString = "http://lorempixel.com/100/100/cats/"
let url = NSURL(string: urlString)!
let data = NSData(contentsOfURL: url)
let image = UIImage(data: data!)

This works in a playground:

iPhone: How to get a UIImage from a url?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜