我可以从 URL 加载 UIImage 吗?

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

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

编辑1


根据@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];
}

当我运行它时,控制台显示:

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

查看调用堆栈,我调用 URLWithString,它调用 URLWithString: relativeToURL: ,然后调用 initWithString: relativeToURL: ,然后调用 _ CFStringIsLegalURLString,然后调用 CFStringGetLlength,然后调用 Forwarding _ prep _ 0,然后调用 转发,然后调用-[ NSObject doesNot認 izeSelector ]。

知道为什么我的 NSString (photoURL 的地址是0x536fbe0)不响应长度吗?为什么它说它不响应-[ NSURL 长度] ?难道它不知道 param 是 NSString 而不是 NSURL 吗?

编辑2


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

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

你可以这样做(同步,但紧凑) :

UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]];

一个更好的方法是使用苹果的 LazyTableImages 来保持交互性。

查看通过 给你提供的 AsyncImageView。一些好的示例代码,甚至可能是可用的权利“开箱即用”为您。

你可以试试 SDWebImage,它提供:

  1. 异步加载
  2. 脱机使用的缓存
  3. 加载时出现的位置持有者图像
  4. 适用于 UITableView

举个简单的例子:

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

AFNetworking 提供了带有占位符支持的异步图像加载到 UIImageView 中。它还通常支持异步网络来处理 API。

获取 DLImageLoader并尝试下面的代码

   [DLImageLoader loadImageFromURL:imageURL
completed:^(NSError *error, NSData *imgData) {
imageView.image = [UIImage imageWithData:imgData];
[imageView setContentMode:UIViewContentModeCenter];


}];

另一个使用 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
}
}];

正如我在上面提到的另一个最近值得考虑的库是 Haneke(不幸的是它不是那么轻量级)。

而迅速的版本是:

   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)

试试这个代码,你可以用它来设置加载图像,这样用户就知道你的应用程序正在从网址加载图像:

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"];
}
});
});

使用 Swift 分机UIImageView的方法(源代码 给你) :

为关联的 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()
})
}
}

自定义初始化器和设置器

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

确保在 iOS9中启用这些设置:

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

enter image description here

然后写下这段代码:

NSURL *url = [[NSURL alloc]initWithString:@"http://feelgrafix.com/data/images/images-1.jpg"];
NSData *data =[NSData dataWithContentsOfURL:url];
quickViewImage.image = [UIImage imageWithData:data];

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

[UIImage imageWithContentsOfFile:url.path]

通过 Url 加载图片的最好和最简单的方法就是使用以下代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data =[NSData dataWithContentsOfURL:[NSURL URLWithString:imgUrl]];


dispatch_async(dispatch_get_main_queue(), ^{
imgView.image= [UIImage imageWithData:data];
});
});

用你的 ImageURL代替 imgUrl
用你的 UIImageView代替 imgView

它将在另一个线程中加载图像,所以它不会减慢应用程序的加载速度。

本地 URL 非常简单,只需使用以下方法:

UIImage(contentsOfFile: url.path)