J'ai une URL pour une image (obtenue auprès de UIImagePickerController) mais je n'ai plus l'image en mémoire (l'URL a été enregistrée à partir d'une exécution précédente de l'application). Puis-je recharger UIImage à partir de l'URL?
Je vois que UIImage a un imageWithContentsOfFile: mais j'ai une URL. Puis-je utiliser dataWithContentsOfURL: de NSData pour lire l'URL?
sur la base de la réponse de @ Daniel, j'ai essayé le code suivant, mais cela ne fonctionne pas ...
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];
}
Quand je l'ai couru la console montre:
-[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'
En regardant la pile d'appels, j'appelle URLWithString, qui appelle URLWithString: relativeToURL :, puis initWithString: relativeToURL :, puis _CFStringIsLegalURLString, puis CFStringGetLength, puis forwarding_prep_0 , transfert , puis - [NSObject ne reconnaît pas de reconnaissance].
Des idées pour lesquelles mon NSString (l'adresse de photoURL est 0x536fbe0) ne répond pas à la longueur? Pourquoi dit-il qu'il ne répond pas à - [longueur de NSURL]? Ne sait-il pas que param est une NSString, pas une NSURL?
OK, le seul problème avec le code est la conversion de chaîne en URL. Si je code la chaîne, tout le reste fonctionne bien. Donc, quelque chose ne va pas avec mon NSString et si je ne peux pas le comprendre, je suppose que cela devrait être une question différente. Avec cette ligne insérée (j'ai collé le chemin du journal de la console ci-dessus), cela fonctionne très bien:
photoURL = @"file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100Apple/IMG_0004.JPG";
Vous pouvez le faire de cette manière (de manière synchrone mais compacte):
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]];
Une meilleure solution consiste à utiliser les LazyTableImages d’Apple pour préserver l’interactivité.
Vous pouvez essayer SDWebImage , il fournit:
Exemple rapide:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
get DLImageLoader et essayez le code suivant
[DLImageLoader loadImageFromURL:imageURL
completed:^(NSError *error, NSData *imgData) {
imageView.image = [UIImage imageWithData:imgData];
[imageView setContentMode:UIViewContentModeCenter];
}];
Un autre exemple typique d'utilisation de DLImageLoader dans le monde réel, qui peut aider quelqu'un ...
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
}
}];
Comme je le mentionne ci-dessus, Haneke est une autre bibliothèque intéressante à considérer de nos jours (malheureusement, elle n’est pas aussi légère).
Si vous êtes vraiment, absolument positivement que le NSURL est une url de fichier, c’est-à-dire que [url isFileURL]
est garanti pour retourner vrai dans votre cas, vous pouvez simplement utiliser:
[UIImage imageWithContentsOfFile:url.path]
Et la version Swift:
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)
Essayez ce code, vous pouvez définir le chargement d’image avec celui-ci, afin que les utilisateurs sachent que votre application charge une image à partir de l’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"];
}
});
});
AFNetworking fournit le chargement d’image asynchrone dans un UIImageView avec prise en charge d’espaces réservés. Il prend également en charge la mise en réseau asynchrone pour travailler avec les API en général.
Consultez la AsyncImageView
fournie sur ici . Un bon exemple de code, et pourrait même être utilisable directement pour vous.
Le chemin en utilisant un Swift Extension à UIImageView
(code source ici ):
UIActivityIndicatorView
associéeimport 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()
}
}
Assurez-vous d’activer ces paramètres depuis iOS 9:
Paramètres de sécurité App Transport dans Info.plist pour garantir le chargement de l'image à partir de l'URL afin qu'il permette de télécharger l'image et de le définir.
Et écrivez ce code:
NSURL *url = [[NSURL alloc]initWithString:@"https://www.google.co.in/"];
NSData *data =[NSData dataWithContentsOfURL:url];
quickViewImage.image = [UIImage imageWithData:data];
Le meilleur moyen de charger une image via une URL est le suivant:
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];
});
});
Remplacez imgUrl
par votre ImageURL
Remplacez imgView
par votre UIImageView
.
Cela chargera l'image dans un autre sujet, afin de ne pas ralentir le chargement de votre application.