IPhone: Как получить UIImage из URL-адреса?

Как загрузить изображение и превратить его в UIImage?

Ответы

Ответ 1

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

Однако это не асинхронно.

Ответ 2

Вы должны помнить, что загрузка данных изображения с помощью кода примера, который вы предоставили в своем собственном ответе, блокирует основной поток до завершения загрузки. Это полезность no-no. Пользователи вашего приложения подумают, что ваше приложение не отвечает. Если вы хотите загрузить изображение, попробуйте NSURLConnection загрузить его асинхронно в своем потоке.

Прочитайте документацию Apple о загрузке async с NSURLConnection.

Когда загрузка будет завершена, вы можете создать экземпляр своего UIImage из объекта данных:

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

Где requestData и image являются переменными экземпляра вашего содержащего класса, а image является сохраненным свойством. Обязательно отпустите image в подпрограмме dealloc класса, например. используя self.image=nil;.

Ответ 3

Верно, что асинхронная загрузка является обязательной, но вы также можете достичь этого с помощью фонового вызова, если вам просто нужно простое решение.

[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?)
       ...
   }
}   

Ответ 5

Основываясь на ответе @philfreo, я создал расширение NSURL в swift с использованием BrightFutures (для асинхронного обратного вызова:

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
    }
}

Это позволяет мне:

import BrightFutures

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

Update

Простое синхронное расширение может выглядеть так:

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

Ответ 6

Вы можете загрузить изображение в UIImageView из URL-адреса без блокировки потока пользовательского интерфейса, просто используя 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];
            });
        });

Первый dispatch_async используется для загрузки изображения из URL в фоновом режиме (без блокировки пользовательского интерфейса). Второй dispatch_async используется для фактического ввода изображения, загруженного только в UIImageView. Обратите внимание, что второй dispatch_async предназначен для работы с основным потоком (потоком пользовательского интерфейса), который действительно является потоком, используемым для обновления пользовательского интерфейса.

Ответ 7

Вот что ответ @philfreo выглядит как быстрый:

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

Это работает на детской площадке:

image