क्या मैं किसी URL से UIImage लोड कर सकता हूं?


134

मेरे पास एक छवि के लिए एक URL है (इसे UIImagePickerController से प्राप्त किया गया है) लेकिन मेरे पास अब मेमोरी में छवि नहीं है (URL ऐप के पिछले भाग से सहेजा गया था)। क्या मैं फिर से URL से UIImage को पुनः लोड कर सकता हूं?

मैं देखता हूं कि UIImage के पास एक imageWithContentsOfFile है: लेकिन मेरे पास एक URL है। क्या मैं URL पढ़ने के लिए NSData के डेटाWithContentsOfURL का उपयोग कर सकता हूं?

EDIT1


@ डैनियल के जवाब के आधार पर मैंने निम्नलिखित कोड की कोशिश की, लेकिन यह काम नहीं करता है ...

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'

:, relativeToURL तो initWithString: कॉल स्टैक, मैं URLWithString फोन कर रहा हूँ, जो URLWithString कॉल को देखते हुए relativeToURL :, तो _CFStringIsLegalURLString, तो CFStringGetLength, तो forwarding_prep_0 , तो अग्रेषण , तो - [NSObject doesNotRecognizeSelector]।

किसी भी विचार क्यों मेरे NSString (photourl का पता 0x536fbe0 है) लंबाई का जवाब नहीं देता है? यह क्यों कहता है कि यह जवाब नहीं देता - [NSURL लंबाई] क्या यह नहीं पता कि परम एक NSString है, एक NSURL नहीं?

EDIT2


ठीक है, कोड के साथ एकमात्र समस्या URL रूपांतरण के लिए स्ट्रिंग है। अगर मैं स्ट्रिंग को हार्डकोड करता हूं, तो बाकी सब ठीक काम करता है। तो मेरे NSString के साथ कुछ गलत है और अगर मैं इसका पता नहीं लगा सकता, तो मुझे लगता है कि एक अलग प्रश्न के रूप में जाना चाहिए। इस पंक्ति को सम्मिलित करने के साथ (मैंने ऊपर कंसोल लॉग से पथ को चिपकाया है), यह ठीक काम करता है:

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

ऐसा लगता है कि photoURL पहले से ही एक NSURL है, न कि NSString, जिसे देखते हुए NSLog ने इसे संभाला।
ड्रॉवर्ड

वापस ले लिया: डॉक्स में एक त्रुटि की तरह लग रहा है। यह कहता है कि UIImagePickerControllerMediaURL एक NSString है, लेकिन यह वास्तव में एक NSURL ऑब्जेक्ट है।
प्रोगराम

लाइब्रेरी DLImageLader INCREDIBLE है। रॉक सॉलिड, नो डोको, वन कमांड और सब कुछ परफेक्ट है। क्या मिला?
फेटी

मैं दूसरा (तीसरा?) DLImageLoader। मुझे इस बारे में संदेह था कि क्या इस पृष्ठ पर इसके बारे में टिप्पणी उद्देश्यपूर्ण थी - लेकिन मैंने इसे वैसे भी आज़माया और यह बहुत अच्छी तरह से काम करता है। मेरे पास UIIableViewCell के भीतर एक UIImageView है। मैंने जो किया वह UIImageView को DLImageView से बदल दिया गया, फिर छवि को लोड करने के लिए ImageFromUrl: विधि कहा जाता है, और यह सब बस काम करता है - अतुल्यकालिक लोडिंग, कैशिंग, आदि आसान नहीं हो सकते।
itnAAnti

DLImageLoader शानदार रहता है एक और अच्छा एक है, Haneke है, हालांकि यह काफी रखरखाव नहीं किया जा रहा से एक छोटे से ग्रस्त है।
फेटी

जवाबों:


319

आप इसे इस तरह से कर सकते हैं (समकालिक, लेकिन कॉम्पैक्ट):

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

एक बहुत ही बेहतर तरीका है Apple का LazyTableImages का इस्तेमाल इंटरेक्टिविटी को संरक्षित करने के लिए।


1
क्या डेटा को PNG (या JPG) फ़ाइल प्रारूप से UIImage डेटा में परिवर्तित करने की आवश्यकता नहीं है? या UIImage आंकड़ा है कि किसी भी तरह बाहर करता है?
प्रोगराम

2
मुझे लगता है कि मुझे सिर्फ RTFM चाहिए, यह UIImage क्लास रेफरेंस में सही कहता है कि यह किस फाइल फॉर्मेट को सपोर्ट और इमेज कर सकता है: कहते हैं कि यह किसी फाइल से डेटा हो सकता है, लगता है कि यह काम करना चाहिए।
प्रात: 19:10

@ डैनियल: काम नहीं किया, मैंने अपना प्रश्न अपने वास्तविक कोड और अपवाद जानकारी को शामिल करने के लिए संपादित किया। यह थोड़ा विचित्र है।
प्रोगराम

@ डैनियल: यह काम करता है अगर मैं एनएसएसट्रिंग के बजाय एक स्ट्रिंग निरंतर का उपयोग करता हूं, जिसमें मैं गुजर रहा था। तो यह नवीनतम समस्या मेरे एनएसएसट्रिंग के साथ कुछ गलत थी, एनएसयूआरएल / एनएसडेट / यूआईआईएमटी कोड के साथ कोई समस्या नहीं है जो काम करती है। धन्यवाद डैनियल!
प्रोगराम

यदि आप केवल एक छवि का उपयोग कर रहे हैं और आप एक त्वरित सुधार की तलाश कर रहे हैं तो आप बस एक ही कोड लिख सकते हैं जो एकल छवि को कैश करता है।
20

27

आप SDWebImage की कोशिश कर सकते हैं , यह प्रदान करता है:

  1. अतुल्यकालिक लोडिंग
  2. ऑफ़लाइन उपयोग के लिए कैशिंग
  3. लोड करते समय दिखाई देने के लिए धारक की छवि रखें
  4. UITableView के साथ अच्छी तरह से काम करता है

त्वरित उदाहरण:

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

2
मैंने उस लाइब्रेरी को थोड़ा संशोधित किया है और इसे आकार / फसल क्षमताओं को जोड़ने के लिए इसे UIImage + Resize के साथ एकीकृत किया है। अगर आपको इसकी आवश्यकता है तो इसे github.com/toptierlabs/ImageCacheResize पर देखें
टोनी

1
यह उदाहरण ए UIImageViewSDWebImageआपको UIImageसीधे उपयोग करने की सुविधा देता है SDWebImageManager - (void) downloadWithURL:...। उनका उदाहरण मुझे पढ़ने पर देखें।
बेंडाईट्री

10

और स्विफ्ट संस्करण:

   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)

7

यदि आप वास्तव में पूरी तरह से सकारात्मक हैं, तो सुनिश्चित करें कि NSURL एक फ़ाइल url है, यानी [url isFileURL]आपके मामले में सही लौटने की गारंटी है, तो आप बस उपयोग कर सकते हैं:

[UIImage imageWithContentsOfFile:url.path]

7

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

जैसा कि मैंने इन दिनों पर विचार करने के लिए एक और महान पुस्तकालय के ऊपर उल्लेख किया है हेंके (दुर्भाग्य से यह उतना हल्का नहीं है)।


1
SDWebImage ऑब्जेक्टिव-सी में सबसे लोकप्रिय लाइब्रेरी है और किंगफिशर स्विफ्ट पोर्ट है।
XY

1
सच है, लेकिन DLImageLoader बेहतर है! :)
फेटी

5

इस कोड को आज़माएं, आप इसके साथ लोडिंग इमेज सेट कर सकते हैं, इसलिए उपयोगकर्ता जानते हैं कि आपका ऐप 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"];
            }
        });
    });

2
मैं इस समाधान को प्राथमिकता देता हूं क्योंकि इसे किसी भी 3 पार्टी फ्रेमवर्क को लोड करने या डेटा लोड करने वाली कतारें, आदि को
तुरंत

4

यहां दिए AsyncImageViewगए चेक को देखें । कुछ अच्छे उदाहरण कोड, और आपके लिए "बॉक्स से बाहर" भी उपयोगी हो सकते हैं।


दिलचस्प उदाहरण, यह पहले के उत्तर में उल्लिखित Apple के LazyTableImages उदाहरण की अवधारणा के समान है।
प्रोगराम

यह समान है, लेकिन सावधान रहें कि AsyncImageView वास्तव में तालिकाओं में काम नहीं करता है, कम से कम तब नहीं जब आप तालिका कोशिकाओं (जैसा आपको चाहिए) को रीसायकल करते हैं।
n13

4

AFNetworking प्लेसहोल्डर समर्थन के साथ एक UIImageView में async छवि लोडिंग प्रदान करता है। यह सामान्य रूप से एपीआई के साथ काम करने के लिए async नेटवर्किंग का भी समर्थन करता है।


3

सुनिश्चित करें कि iOS 9 से इस सेटिंग को सक्षम करें:

URL से लोडिंग छवि सुनिश्चित करने के लिए Info.plist में ऐप ट्रांसपोर्ट सिक्योरिटी सेटिंग्स ताकि यह डाउनलोड इमेज को अनुमति दे और इसे सेट कर सके।

यहाँ छवि विवरण दर्ज करें

और यह कोड लिखें:

NSURL *url = [[NSURL alloc]initWithString:@"http://feelgrafix.com/data/images/images-1.jpg"];
NSData *data =[NSData dataWithContentsOfURL:url];
quickViewImage.image = [UIImage imageWithData:data];

2

जिस तरह से एक स्विफ्ट का उपयोग कर विस्तार करने के लिए 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()
    }
}

0

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

यह इमेज को दूसरे थ्रेड में लोड करेगा, इसलिए यह आपके ऐप लोड को धीमा नहीं करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.