ios 我可以从 URL 加载 UIImage 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2782454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:12:09  来源:igfitidea点击:

Can I load a UIImage from a URL?

iosiphoneuiimageuiimagepickercontroller

提问by progrmr

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?

我有一个图像的 URL(从 UIImagePickerController 获得),但我的内存中不再有图像(该 URL 是从之前运行的应用程序中保存的)。我可以再次从 URL 重新加载 UIImage 吗?

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

我看到 UIImage 有一个 imageWithContentsOfFile: 但我有一个 URL。我可以使用 NSData 的 dataWithContentsOfURL: 来读取 URL 吗?

EDIT1

编辑1



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

基于@Daniel 的回答,我尝试了以下代码,但它不起作用...

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

查看调用堆栈,我正在调用 URLWithString,它调用 URLWithString:relativeToURL:,然后是 initWithString:relativeToURL:,然后是 _CFStringIsLegalURLString,然后是 CFStringGetLength,然后是forwarding_prep_0,然后是forwarding,然后是 -[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?

任何想法为什么我的 NSString(photoURL 的地址是 0x536fbe0)不响应长度?为什么它说它不响应 -[NSURL length]?难道它不知道 param 是一个 NSString,而不是一个 NSURL?

EDIT2

编辑2



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:

好的,代码唯一的问题是字符串到 URL 的转换。如果我对字符串进行硬编码,则其他一切正常。所以我的 NSString 有问题,如果我无法弄清楚,我想这应该作为一个不同的问题。插入这一行(我粘贴了上面控制台日志中的路径),它工作正常:

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

回答by Daniel Blezek

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.

更好的方法是使用 Apple 的 LazyTableImages 来保持交互性。

回答by Muhammad Hassan Nasr

You can try SDWebImage, it provides:

您可以尝试SDWebImage,它提供:

  1. Asynchronous loading
  2. Caching for offline use
  3. Place holder image to appear while loading
  4. Works well with UITableView
  1. 异步加载
  2. 缓存供离线使用
  3. 加载时显示的占位符图像
  4. 与 UITableView 配合使用

Quick example:

快速示例:

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

回答by user3763002

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)

回答by Muruganandham K

get DLImageLoaderand try folowing code

获取DLImageLoader并尝试以下代码

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

使用 DLImageLoader 的另一个典型的现实世界示例,它可能会帮助某人...

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

正如我在上面提到的,最近要考虑的另一个很棒的库是Haneke(不幸的是,它没有那么轻量级)。

回答by Dhiraj Gupta

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

如果你真的,绝对是积极肯定的NSURL是一个文件的URL,即[url isFileURL]是保证在你的情况下返回true,那么你可以简单地使用:

[UIImage imageWithContentsOfFile:url.path]

回答by Jouhar

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

试试这个代码,你可以用它设置加载图片,这样用户就知道你的应用正在从 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"];
            }
        });
    });

回答by pauliephonic

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

AFNetworking提供异步图像加载到具有占位符支持的 UIImageView。它还支持异步网络以使用一般的 API。

回答by marcc

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

查看此处AsyncImageView提供的内容。一些很好的示例代码,甚至可能对您来说“开箱即用”。

回答by Nagarjun

Make sure enable this settings from iOS 9:

确保从 iOS 9 启用此设置:

App Transport Security Settingsin Info.plistto ensure loading image from URL so that it will allow download image and set it.

Info.plist 中的应用传输安全设置,以确保从 URL 加载图像,以便它允许下载图像并进行设置。

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

回答by fpg1503

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

使用 Swift扩展的方式UIImageView(源代码在这里):

Creating Computed Property for Associated UIActivityIndicatorView

为关联创建计算属性 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()
    }
}