2010-03-23 14 views
43

Ich versuche, das Bild aus der URL http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpgiOS: Bild von URL herunterladen und in dem Gerät speichern

Ich verwende den folgenden Code zum Download, aber Bild wird nicht im Gerät gespeichert. Ich möchte wissen, was ich falsch mache.

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]]; 
[NSURLConnection connectionWithRequest:request delegate:self]; 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"]; 
NSData *thedata = NULL; 
[thedata writeToFile:localFilePath atomically:YES]; 

UIImage *img = [[UIImage alloc] initWithData:thedata]; 
+7

Warum zum Teufel machst du dies: 'NSData * thedata = NULL;'? – Jasarien

+0

Dies ist eine Lösung: http://jayprakashdubey.blogspot.in/2014/09/load-image-from-existing-location-and.html –

+0

@Jasarien, weil er eine Frage stellt ... lol – quemeful

Antwort

34

Wenn Sie theData-nil gesetzt, was erwartest du es auf die Platte zu schreiben?

Was Sie verwenden können, ist NSData* theData = [NSData dataWithContentsOfURL:yourURLHere];, um die Daten von der Festplatte zu laden und speichern Sie sie dann mit writeToFile:atomically:. Wenn Sie mehr Kontrolle über den Ladevorgang benötigen oder im Hintergrund haben, sehen Sie sich die Dokumentation von NSURLConnection und die zugehörige Anleitung an.

2

Hallo Es ist klar, dass Sie NULL-Daten in Ihre Datei schreiben.

In Ihrer Code-Anweisung NSData * thedata = NULL; zeigt an, dass Sie Ihren Daten einen NULL-Wert zuweisen.

Sie schreiben auch NULL-Daten in Ihre Datei.

Bitte überprüfen Sie Ihren Code noch einmal.

+0

Beachten Sie, dass das Senden einer Selektor auf Null hat keinen Effekt, also wird eigentlich nichts auf Platte geschrieben (nicht einmal Null-Daten). Ist in diesem Fall nicht wirklich wichtig, sondern nur um den feinen Unterschied aufzuzeigen. – Alfonso

+0

danke jim, jetzt ist mein Problem gelöst – User97693321

9

Dies ist der Code zum Herunterladen des Bildes von der URL und speichern Sie das Bild im Gerät und this ist der Referenzlink.

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]]; 
[NSURLConnection connectionWithRequest:request delegate:self]; 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:@"pkm.jpg"]; 
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg"]]; 
[thedata writeToFile:localFilePath atomically:YES]; 
+0

Warum machst du einen asynchronen Aufruf mit NSURLConnection und dann mit einem synchronen Aufruf an [NSData dataWithContentsOfURL ...]? Der NSURLConnection-Teil bleibt einfach hängen und tut nichts - aber er wird trotzdem Daten aus dem Netzwerk ziehen und sie anschließend verwerfen. – SaltyNuts

+0

Danke für guten Vorschlag, war mir nicht bewusst. – User97693321

+0

@ Benutzer97693321. Wie kann ich mehrere Bilder hinzufügen, die vom Webservice analysiert werden? –

97

Ich habe genau das, was Sie suchen.

Get Bild von URL

-(UIImage *) getImageFromURL:(NSString *)fileURL { 
    UIImage * result; 

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; 
    result = [UIImage imageWithData:data]; 

    return result; 
} 

Bild speichern

-(void) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath { 
    if ([[extension lowercaseString] isEqualToString:@"png"]) { 
     [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil]; 
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) { 
     [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil]; 
    } else { 
     NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension); 
    } 
} 

Bild laden

-(UIImage *) loadImage:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath { 
    UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.%@", directoryPath, fileName, extension]]; 

    return result; 
} 

How-To

//Definitions 
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 

//Get Image From URL 
UIImage * imageFromURL = [self getImageFromURL:@"http://www.yourdomain.com/yourImage.png"]; 

//Save Image to Directory 
[self saveImage:imageFromURL withFileName:@"My Image" ofType:@"png" inDirectory:documentsDirectoryPath]; 

//Load Image From Directory 
UIImage * imageFromWeb = [self loadImage:@"My Image" ofType:@"png" inDirectory:documentsDirectoryPath]; 
+9

Wenn Sie ein Bild mit der Erwartung herunterladen, es lokal zu speichern und nicht nur anzuzeigen, wäre es wahrscheinlich besser, die Datei direkt mit [data writeToFile: options: error:] zu erstellen, anstatt sie in einem UIImage-Objekt zu speichern zuerst. Auf diese Weise vermeiden Sie, das Bild erneut zu komprimieren und dabei EXIF-Daten zu verlieren. – SaltyNuts

+2

Wenn du meinen Code magst, kannst du mein Open-Source-Projekt Atom herunterladen, das die oben genannten Methoden und vieles mehr enthält. (https://github.com/fer94/atom) –

+0

Verwenden Sie getImageFromURL nicht zum Herunterladen großer Bilder, da dies den Hauptthread blockieren kann, was zu einer nicht reagierenden Benutzeroberfläche führt. Verwenden Sie eine Alternative, die das Bild auf einen Hintergrundthread herunterlädt. Mehr unter https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html – m177312

2

Da wir auf iOS6 jetzt sind, müssen Sie nicht mehr neccessarily Bilder auf die Festplatte zu schreiben.
Seit iOS5 können Sie nun "Erlaube externen Speicher" auf einem Coreedata-Binärattribut einstellen. Nach Äpfeln Release Notes es bedeutet folgendes:

Small data values like image thumbnails may be efficiently stored in a database, but laarge photos or other media are best handled directly by the file system. You can now specify that the value of a managed object attribute may be stored as an external record - see setAllowsExternalBinaryDataStorage: When enabled, Core Data heuristically decides on a per-value basis if it should save the data directly in the database or store a URI to a separate file which it manages for you. You cannot query based on the contents of a binary data property if you use this option.

4

Get Image From URL

-(UIImage *) getImageFromURL:(NSString *)fileURL { 
    UIImage * result; 

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; 
    result = [UIImage imageWithData:data]; 

    return result; 
} 

Das funktionierte gut für mich, aber ich lief in den Speicher Probleme mit cfdata (Speicher). Fest es mit einem autoreleasepool:

-(UIImage *) getImageFromURL:(NSString *)fileURL { 
    @autoreleasepool { 
    UIImage * result; 

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; 
    result = [UIImage imageWithData:data]; 

    return result; 
    } 
} 
2
-(IBAction)BtnDwn:(id)sender 
{ 
    [self.actvityIndicator startAnimating]; 

    NSURL *URL = [NSURL URLWithString:self.dataaArray]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 
    NSURLSession *session = [NSURLSession sharedSession]; 

    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) 
    { 

     NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; 
     NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath]; 
     NSURL *documentURL = [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; 
     BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:[documentURL path]]; 

     if (exists) 
     { 
     NSLog(@"not created"); 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download" 
                message:@"sory,file already exists" 
                delegate:nil 
              cancelButtonTitle:@"cancel" 
              otherButtonTitles:nil]; 
     [alert show]; 
     } 
     else 
     { 
     [[NSFileManager defaultManager] moveItemAtURL:location toURL:documentURL error:nil]; 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Download" 
                message:@"Succesfully downloaded" 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil]; 
     [self.actvityIndicator stopAnimating]; 
     NSLog(@"wait downloading......"); 
     [alert show]; 
    } 
    }]; 

    [downloadTask resume];  
} 
0

Hier ist ein Beispiel dafür, wie ich Banner auf meine App herunterladen. Ich lade die Bilder im Hintergrund herunter, und die meisten meiner Apps verwenden keine Referenzzählung, daher gebe ich Objekte frei.

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [NSThread detachNewThreadSelector:@selector(loadImageInBackground) toTarget:self withObject:nil]; 

} 

- (void) loadImageInBackground { 
    NSURL *url = [[NSURL alloc] initWithString:@"http://yourImagePath.png"]; 
    NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 
    [url release]; 
    UIImage *result = [[UIImage alloc] initWithData:data]; 
    [data release]; 

    UIImageView *banner_ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; 
    [self.view addSubview:banner_ImageView]; 
    banner_ImageView.image = result; 
    [result release]; 
} 
0

Hier ist, wie Sie ein Bild asynchron in Swift speichern:

requestImage("http://www.asdf.com/89asdf.gif") { (image) -> Void in 
    let myImage = image 
} 

func requestImage(url: String, success: (UIImage?) -> Void) { 
    requestURL(url, success: { (data) -> Void in 
     if let d = data { 
      success(UIImage(data: d)) 
     } 
    }) 
} 

func requestURL(url: String, success: (NSData?) -> Void, error: ((NSError) -> Void)? = nil) { 
    NSURLConnection.sendAsynchronousRequest(
     NSURLRequest(URL: NSURL (string: url)!), 
     queue: NSOperationQueue.mainQueue(), 
     completionHandler: { response, data, err in 
      if let e = err { 
       error?(e) 
      } else { 
       success(data) 
      } 
    }) 
} 

Sein als Standardfunktion in meinem Repo enthalten:

https://github.com/goktugyil/EZSwiftExtensions

Verwandte Themen