我可以从URL加载UIImage?
我有一个图像的URL(从UIImagePickerController得到它),但我不再有内存中的图像(该URL是从以前的应用程序运行保存)。 我可以重新从URL重新加载UIImage?
我看到UIImage有一个imageWithContentsOfFile:但我有一个URL。 我可以使用NSData的dataWithContentsOfURL:读取URL?
EDIT1
基于@ 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,然后CFStringGetLength,然后forwarding_prep_0 ,然后转发 ,然后 – [NSObject doesNotRecognizeSelector]。
任何想法,为什么我的NSString(photoURL的地址是0x536fbe0)不响应的长度? 为什么说它不响应 – [NSURL长度]? 不知道param是NSString,而不是NSURL?
EDIT2
好的,代码唯一的问题是URL转换的string。 如果我硬编码的string,一切工作正常。 所以,我的NSString有些问题,如果我弄不明白,我想这应该是一个不同的问题。 插入这条线(我从上面的控制台日志粘贴path),它工作正常:
photoURL = @"file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG";
你可以这样做(同步,但紧凑):
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]];
更好的方法是使用Apple的LazyTableImages来保持交互性。
您可以尝试SDWebImage ,它提供:
- asynchronous加载
- caching以供离线使用
- 加载时出现占位符图像
- 适用于UITableView
快速示例:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
得到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 } }];
正如我上面提到的另一个伟大的图书馆考虑这些天是哈奈克 (不幸的是它不是轻量级)。
而迅捷版本:
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)
试试这个代码,你可以设置加载图像,所以用户知道你的应用程序正在从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"]; } }); });
看看这里提供的AsyncImageView
。 一些很好的示例代码,甚至可以为您“开箱即用”。
AFNetworking使用占位符支持将asynchronous图像加载到UIImageView中。 它还支持一般使用API的asynchronousnetworking。
如果你是真的 ,绝对肯定NSURL是一个文件的URL,即[url isFileURL]
保证在你的情况下返回true,那么你可以简单地使用:
[UIImage imageWithContentsOfFile:url.path]
使用Swift 扩展到UIImageView
(源代码在这里 )的方式:
为关联的UIActivityIndicatorView
创build计算属性
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() } }
请确保从iOS 9启用此设置:
Info.plist中的 应用传输安全设置 ,确保从URL加载图像,以便允许下载图像并进行设置。
并写下这段代码:
NSURL *url = [[NSURL alloc]initWithString:@"https://www.google.co.in/"]; NSData *data =[NSData dataWithContentsOfURL:url]; quickViewImage.image = [UIImage imageWithData:data];