web-dev-qa-db-fra.com

Puis-je charger un UIImage à partir d'une URL?

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?

EDIT1


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?

EDIT2


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";
127
progrmr

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é.

311
Daniel Blezek

Vous pouvez essayer SDWebImage , il fournit:

  1. Chargement asynchrone
  2. Mise en cache pour une utilisation hors connexion
  3. Placez l'image de titulaire à apparaître lors du chargement
  4. Fonctionne bien avec UITableView

Exemple rapide:

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

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).

7
Muruganandham K

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]
6
Dhiraj Gupta

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)
5
user3763002

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

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.

4
pauliephonic

Consultez la AsyncImageView fournie sur ici . Un bon exemple de code, et pourrait même être utilisable directement pour vous.

4
marcc

Le chemin en utilisant un Swift Extension à UIImageView (code source ici ):

Création d'une propriété calculée pour la variable UIActivityIndicatorView associée

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

Initialiseur et configurateur personnalisés

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

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.

 enter image description here

Et écrivez ce code:

NSURL *url = [[NSURL alloc]initWithString:@"https://www.google.co.in/"];
NSData *data =[NSData dataWithContentsOfURL:url];
quickViewImage.image = [UIImage imageWithData:data];
2
Nagarjun

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.

0
jalmatari