141 votes

Est-ce que je peux charger une UIImage à partir d'une URL ?

J'ai une URL pour une image (obtenue à partir de UIImagePickerController) mais je n'ai plus l'image en mémoire (l'URL a été sauvegardée lors d'une exécution précédente de l'application). Puis-je recharger l'UIImage à partir de l'URL à nouveau?

Je vois que UIImage a une imageWithContentsOfFile: mais j'ai une URL. Puis-je utiliser dataWithContentsOfURL: de NSData pour lire l'URL?

MODIFICATION1


Basé sur 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];
}

Lorsque je l'ai exécuté, la console affiche:

-[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, puis forwarding, puis -[NSObject doesNotRecognizeSelector].

Des idées pourquoi mon NSString (l'adresse de photoURL est 0x536fbe0) ne répond pas à length? Pourquoi dit-il qu'il ne répond pas à -[NSURL length]? Ne sait-il pas que le paramètre est une NSString, pas une NSURL?

MODIFICATION2


D'accord, le seul problème avec le code est la conversion de la chaîne en URL. Si je définis en dur la chaîne, tout le reste fonctionne bien. Donc quelque chose ne va pas avec mon NSString et si je ne peux pas le résoudre, je suppose que cela devrait être une autre question. Avec cette ligne insérée (j'ai copié le chemin à partir du journal de la console ci-dessus), tout fonctionne correctement:

photoURL = @"file://localhost/Users/gary/Library/Application%20Support/iPhone%20Simulator/3.2/Media/DCIM/100APPLE/IMG_0004.JPG";

0 votes

Il semble que photoURL est déjà une NSURL, pas une NSString, étant donné que NSLog l'a traité.

0 votes

@drawn: Il semble y avoir une erreur dans la documentation. Il est indiqué que UIImagePickerControllerMediaURL est une NSString mais c'est en fait un objet NSURL.

0 votes

La bibliothèque DLImageLoader est INCROYABLE. solide comme un roc, sans documentation, une seule commande et tout est parfait. Quelle trouvaille.

328voto

Daniel Blezek Points 2682

Vous pouvez le faire de cette manière (de manière synchrone, mais compacte) :

UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:MyURL]]];

Une approche bien meilleure est d'utiliser LazyTableImages d'Apple pour préserver l'interactivité.

1 votes

La donnée doit-elle être convertie du format de fichier PNG (ou JPG) en données UIImage ? Ou est-ce qu'UIImage le gère d'une certaine façon ?

2 votes

Je suppose que je devrais juste lire le manuel, il est indiqué dans la référence de classe UIImage quels formats de fichier il peut prendre en charge et imageWithData : dit qu'il peut s'agir de données d'un fichier, cela devrait fonctionner.

0 votes

@Daniel : ça n'a pas fonctionné, j'ai modifié ma question pour inclure mon code réel et les informations sur l'exception. C'est un peu bizarre.

27voto

Muhammad Hassan Points 755

Vous pouvez essayer SDWebImage, il fournit :

  1. Chargement asynchrone
  2. Mise en cache pour une utilisation hors ligne
  3. Image de remplacement pour apparaître pendant le 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"]];

2 votes

J'ai modifié cette bibliothèque un peu et intégré avec UIImage+Resize afin d'ajouter des capacités de redimensionnement/recadrage. Si vous en avez besoin, consultez-le sur github.com/toptierlabs/ImageCacheResize

1 votes

Cet exemple remplit un UIImageView. SDWebImage vous permet également de remplir directement un UIImage en utilisant SDWebImageManager - (void) downloadWithURL:.... Voir leur exemple dans le readme.

13voto

user3763002 Points 61

Et la version rapide :

   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)

7voto

iTroyd23 Points 1705

Obtenir DLImageLoader et essayer 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 l'ai mentionné ci-dessus, une autre excellente bibliothèque à considérer de nos jours est Haneke (malheureusement, elle n'est pas aussi légère).

1 votes

SDWebImage est la bibliothèque la plus populaire en Objective-C et KingFisher est le port Swift.

1 votes

Vrai, mais DLImageLoader est meilleur! :)

4voto

marcc Points 8513

Découvrez le AsyncImageView fourni ici ici. Un bon exemple de code, et il pourrait même être utilisable directement pour vous.

0 votes

Exemple intéressant, il est très similaire dans le concept à l'exemple LazyTableImages d'Apple mentionné dans la réponse précédente.

0 votes

C'est similaire mais attention, AsyncImageView ne fonctionne vraiment pas dans les tables, du moins pas lorsque vous recyclez les cellules de table (comme vous le devriez).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X