繁体   English   中英

iOS:从网址下载图片并保存在设备中

[英]iOS: Download image from url and save in device

我想从网址http://a3.twimg.com/profile_images/414797877/05052008321_bigger.jpg下载图片

我使用以下代码,但图像未保存在设备中。 我想知道我做错了什么。

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

我碰巧有你正在寻找的东西。

从URL获取图像

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

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

    return result;
}

保存图片

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

加载图片

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

    return result;
}

如何

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

如果将theData设置为nil ,您希望它写入磁盘的内容是什么?

您可以使用的是NSData* theData = [NSData dataWithContentsOfURL:yourURLHere]; 从磁盘加载数据,然后使用writeToFile:atomically:保存它writeToFile:atomically: . 如果您需要更多地控制加载过程或将其置于后台,请查看NSURLConnection的文档和相关指南。

这是从url下载图像并将该图像保存在设备中的代码, 是参考链接。

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

从URL获取图像

 -(UIImage *) getImageFromURL:(NSString *)fileURL { UIImage * result; NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]]; result = [UIImage imageWithData:data]; return result; } 

这对我很有用,但我遇到了CFData(商店)的内存问题。 用autoreleasepool修复它:

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

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

     return result;
    }
 }

由于我们现在使用的是IOS6,因此您不再需要将映像写入磁盘。
从iOS5开始,您现在可以在coredata二进制属性上设置“允许外部存储”。 根据苹果发行说明,它意味着以下内容:

像图像缩略图这样的小数据值可以有效地存储在数据库中,但是大型照片或其他媒体最好由文件系统直接处理。 您现在可以指定托管对象属性的值可以存储为外部记录 - 请参阅setAllowsExternalBinaryDataStorage:启用时,如果核心数据应该直接在数据库中保存数据或存储URI,则会根据每个值进行启发式决策到它为您管理的单独文件。 如果使用此选项,则无法基于二进制数据属性的内容进行查询。

您很清楚,您正在将NULL数据写入您的文件。

在你的代码语句NSData * thedata = NULL; 表示您为数据分配NULL值。

您也正在将NULL数据写入文件。

请再次检查您的代码。

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

以下是在Swift中异步保存图像的方法:

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

它包含在我的回购中作为标准功能:

https://github.com/goktugyil/EZSwiftExtensions

这是我如何下载横幅到我的应用程序的示例。 我在后台下载图像,我的大多数应用程序都不使用引用计数,所以我发布了对象。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM