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
Can I load a UIImage from a URL?
提问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,它提供:
- Asynchronous loading
- Caching for offline use
- Place holder image to appear while loading
- Works well with UITableView
- 异步加载
- 缓存供离线使用
- 加载时显示的占位符图像
- 与 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
回答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 加载图像,以便它允许下载图像并进行设置。
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()
}
}