Могу ли я загрузить UIImage из URL-адреса?
У меня есть URL для изображения (получен из UIImagePickerController), но у меня больше нет изображения в памяти (URL-адрес был сохранен из предыдущего запуска приложения). Могу ли я снова загрузить UIImage из URL?
Я вижу, что UIImage имеет imageWithContentsOfFile: но у меня есть URL. Могу ли я использовать данные NSDataWithContentsOfURL: читать 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. Если я жестко кодирую строку, все остальное работает нормально. Так что что-то не так с моей NSString, и если я не могу понять это, я думаю, это должно идти как другой вопрос. Когда эта строка вставлена (я вставил путь из журнала консоли выше), он отлично работает:
photoURL = @"file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG";
Ответы
Ответ 1
Вы можете сделать это так (синхронно, но компактно):
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]];
Гораздо лучший подход - использовать Apple LazyTableImages для сохранения интерактивности.
Ответ 2
Вы можете попробовать SDWebImage, он обеспечивает:
- Асинхронная загрузка
- Кэширование для автономного использования
- Поместите изображение держателя места во время загрузки.
- Хорошо работает с UITableView
Быстрый пример:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
Ответ 3
получить 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 (к сожалению, она не такая легкая).
Ответ 4
И быстрая версия:
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)
Ответ 5
Если вы действительно, абсолютно положительно уверены, что NSURL является URL-адресом файла, т.е. [url isFileURL]
гарантированно вернет true в вашем случае, вы можете просто использовать:
[UIImage imageWithContentsOfFile:url.path]
Ответ 6
Попробуйте этот код, вы можете установить для него загрузку изображения, чтобы пользователи знали, что ваше приложение загружает изображение с 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"];
}
});
});
Ответ 7
Ознакомьтесь с AsyncImageView
, предоставленным здесь. Какой-то хороший примерный код, и его можно даже использовать прямо "из коробки" для вас.
Ответ 8
AFNetworking обеспечивает загрузку асинхронного изображения в UIImageView с поддержкой заполнителя. Он также поддерживает асинхронную сеть для работы с API в целом.
Ответ 9
Обязательно включите эти настройки из iOS 9:
Установите параметры безопасности транспорта в 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];
Ответ 10
Способ использования Swift Extension до 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()
}
}
Ответ 11
Лучший и простой способ загрузить изображение через 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];
});
});
Замените imgUrl
на ваш ImageURL
Замените imgView
на ваш UIImageView
.
Он загрузит изображение в другой поток, поэтому он не замедлит загрузку вашего приложения.