wake-up-neo.com

Kann ich ein UIImage von einer URL laden?

Ich habe eine URL für ein Bild (habe es von UIImagePickerController erhalten), aber ich habe das Bild nicht mehr im Speicher (die URL wurde von einer vorherigen Ausführung der App gespeichert). Kann ich den UIImage erneut von der URL laden? 

Ich sehe, dass UIImage ein imageWithContentsOfFile hat: aber ich habe eine URL. Kann ich die dataWithContentsOfURL: -Datei von NSData verwenden, um die URL zu lesen?

EDIT1


basierend auf @ Daniel's Antwort habe ich den folgenden Code ausprobiert, aber es funktioniert nicht ...

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];
}

Wenn ich es lief, zeigt die Konsole:

-[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'

Wenn ich mir den Call Stack ansehe, rufe ich URLWithString auf, der URLWithString: relativeToURL:, dann initWithString: relativeToURL:, dann _CFStringIsLegalURLString, dann CFStringGetLength, dann forwarding_prep_0 , then forward/- dann/- forwarding , then/--rachnadeln ].

Irgendwelche Ideen, warum mein NSString (die Adresse von photoURL ist 0x536fbe0) nicht auf Länge reagiert? Warum sagt es, dass es nicht auf - [NSURL-Länge] reagiert? Weiß es nicht, dass param ein NSString ist, keine NSURL?

EDIT2


OK, das einzige Problem mit dem Code ist die Umwandlung von String in URL. Wenn ich die Zeichenfolge hardcodeet, funktioniert alles andere gut. Mit meinem NSString stimmt also etwas nicht, und wenn ich es nicht herausfinden kann, denke ich, dass dies eine andere Frage sein sollte. Mit dieser eingefügten Zeile (ich habe den Pfad aus dem Konsolenprotokoll oben eingefügt), funktioniert es gut:

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

Sie können es so machen (synchron, aber kompakt):

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

Ein viel besserer Ansatz ist die Verwendung von LazyTableImages von Apple, um die Interaktivität zu erhalten.

311
Daniel Blezek

Sie können SDWebImage ausprobieren.

  1. Asynchrones Laden
  2. Zwischenspeicherung für die Offline-Verwendung
  3. Platzieren Sie das Bild des Inhabers, um beim Laden zu erscheinen
  4. Funktioniert gut mit UITableView

Schnelles Beispiel:

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

holen Sie sich DLImageLoader und versuchen Sie den folgenden Code

   [DLImageLoader loadImageFromURL:imageURL
                          completed:^(NSError *error, NSData *imgData) {
                              imageView.image = [UIImage imageWithData:imgData];
                              [imageView setContentMode:UIViewContentModeCenter];

                          }];

Ein weiteres typisches Beispiel für die Verwendung von DLImageLoader, das jemandem helfen kann ...

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
        }
    }];

Wie ich oben erwähnte, ist Haneke eine andere großartige Bibliothek, die man in Betracht ziehen muss (leider ist sie nicht so leicht).

7
Muruganandham K

Wenn Sie wirklich, absolut positiv sicher sind, dass die NSURL eine Datei-URL ist, d. H. [url isFileURL] in Ihrem Fall garantiert true zurückgibt, können Sie Folgendes verwenden: 

[UIImage imageWithContentsOfFile:url.path]
6
Dhiraj Gupta

Und die Swift-Version:

   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

Probieren Sie diesen Code aus. Sie können festlegen, dass das Image geladen wird, sodass die Benutzer wissen, dass Ihre App ein Image von der URL lädt:

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 bietet asynchrones Laden von Bildern in eine UIImageView mit Platzhalter-Unterstützung. Es unterstützt auch asynchrone Netzwerke für das Arbeiten mit APIs im Allgemeinen.

4
pauliephonic

Überprüfen Sie die AsyncImageView, die über here bereitgestellt wird. Ein guter Beispielcode, der sogar "out of the box" für Sie verwendbar ist.

4
marcc

Der Weg mit einer Swift Extension zu UIImageView (Quellcode hier ):

Berechnete Eigenschaft für verknüpfte UIActivityIndicatorView erstellen

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

Benutzerdefinierter Initialisierer und Setter

    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

Stellen Sie sicher, dass Sie diese Einstellungen von iOS 9 aus aktivieren:

App-Transportsicherheitseinstellungen in Info.plist, um sicherzustellen, dass das Bild von der URL geladen wird, damit das Bild heruntergeladen und eingestellt werden kann.

 enter image description here

Und schreibe diesen Code:

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

Der beste und einfachste Weg, ein Bild über eine URL zu laden, ist folgender Code:

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

Ersetzen Sie imgUrl durch Ihre ImageURL
Ersetzen Sie imgView durch Ihre UIImageView.

Das Image wird in einem anderen Thread geladen, sodass das Laden der App nicht verlangsamt wird.

0
jalmatari