iPhone:如何从 url 获取 UIImage?

发布于 2024-08-11 16:30:59 字数 28 浏览 1 评论 0原文

如何下载图像并将其转换为 UIImage?

How do you download an image and turn it into a UIImage?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

优雅的叶子 2024-08-18 16:30:59
NSURL *url = [NSURL URLWithString:@"http://example.com/image.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[[UIImage alloc] initWithData:data] autorelease];

但是,这不是异步的。

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.

倦话 2024-08-18 16:30:59

您应该记住,使用您在自己的答案中提供的示例代码加载图像数据将阻塞主线程,直到下载完成。这是可用性禁忌。您的应用程序的用户会认为您的应用程序没有响应。如果你想下载图像,更喜欢 NSURLConnection 在它自己的线程中异步下载它。

阅读有关使用 NSURLConnection 进行异步下载的 Apple 文档。< /a>

下载完成后,您可以从数据对象实例化您的 UIImage:

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

其中 requestDataimage 是包含类的实例变量,image 是保留的属性。请务必在类的 dealloc 例程中释放 image,例如使用 self.image=nil;

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

放飞的风筝 2024-08-18 16:30:59

确实,异步加载是必须的,但如果您只需要一个简单的解决方案,也可以通过后台调用来实现。

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

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?)
       ...
   }
}   
删除会话 2024-08-18 16:30:59

您可以从 URL 加载 UIImageView 中的图像,而无需阻塞 UI 线程,只需使用 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 的图像(不阻塞 UI)。第二个 dispatch_async 用于实际注入刚刚加载到 UIImageView 中的图像。请注意,第二个 dispatch_async 设计为在主线程(UI 线程)上工作,即用于更新 UI 的线程。

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.

梦情居士 2024-08-18 16:30:59

根据@philfreo的回答,我使用 BrightFutures 快速创建了一个 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
    }
}

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
    }
}
伊面 2024-08-18 16:30:59

这就是 @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!)

这在操场上有效:

image

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:

image

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文