簡體   English   中英

iPhone:如何從網址獲取UIImage?

[英]iPhone: How to get a UIImage from a url?

你如何下載圖像並將其轉換為UIImage?

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

但是,這不是異步的。

您應該記住,使用您在自己的答案中提供的示例代碼加載圖像數據將阻止主線程,直到下載完成。 這是禁忌的可用性。 您應用的用戶會認為您的應用沒有響應。 如果要下載圖像,請更喜歡NSURLConnection在其自己的線程中異步下載。

閱讀有關使用NSURLConnection進行異步下載的Apple文檔。

下載完成后,您可以從數據對象中實例化UIImage:

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

其中requestDataimage是包含類的實例變量,而image是保留屬性。 一定要在類的dealloc例程中釋放image ,例如使用self.image=nil;

確實,異步加載是必須的,但如果您只需要一個簡單的解決方案,也可以通過后台調用實現。

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

您可以從URL加載UIImageView的圖像,而無需使用dispatch_async阻止UI線程:

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中的圖像(不阻止UI)。 第二個dispatch_async用於實際注入剛加載到UIImageView的圖像。 請注意,第二個dispatch_async設計用於主線程 (UI線程),實際上是用於更新UI的線程。

根據@ philfreo的回答,我使用BrightFutures在swift中創建了一個NSURL擴展(用於異步回調:

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
}

更新

簡單的同步擴展可能如下所示:

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

這就是@ philfreo在swift中的答案:

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

這適用於游樂場:

圖片

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM