【问题标题】:iOS: Download image from url and save in deviceiOS:从 url 下载图像并保存在设备中
【发布时间】:2011-01-30 17:56:45
【问题描述】:

我正在尝试从网址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];

【问题讨论】:

标签: iphone ios image cocoa-touch ipad


【解决方案1】:

这是在 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

【讨论】:

    【解决方案2】:

    以下是我如何将横幅下载到我的应用程序的示例。我在后台下载图片,我的大多数应用程序不使用引用计数,所以我释放对象。

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

    【讨论】:

      【解决方案3】:
      -(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];    
      }
      

      【讨论】:

        【解决方案4】:

        我恰好有你要找的东西。

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

        【讨论】:

        • 如果您下载图像并希望将其保存在本地而不只是显示它,最好立即使用 [data writeToFile:options:error:] 创建文件,而不是首先将其保存在 UIImage 对象中。这样您就可以避免重新压缩图像并在此过程中丢失所有 EXIF 数据。
        • 如果你喜欢我的代码,请随意下载我的开源项目Atom,其中包括上述方法等等。 (github.com/fer94/atom)
        • 请勿使用 getImageFromURL 下载大图,因为它可能会阻塞主线程,导致 UI 无响应。使用在后台线程上下载图像的替代方法。更多关于developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
        • 这正是我想要的。如果你想下载图片并保存在本地,这个值得一试。
        【解决方案5】:

        您好,很明显您正在将 NULL 数据写入文件。

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

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

        请再次检查您的代码。

        【讨论】:

        • 请注意,将选择器发送到 nil 没有任何效果,因此实际上没有任何内容写入磁盘(甚至没有空数据)。在这种情况下并不重要,只是为了指出细微的差别。
        【解决方案6】:

        从网址获取图片

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

        这对我很有用,但我遇到了 CFData(存储)的内存问题。使用自动释放池修复它:

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

          • 你为什么要使用 NSURLConnection 进行异步调用,然后再使用同步调用 [NSData dataWithContentsOfURL...]? NSURLConnection 部分只是挂起,什么都不做 - 但它仍会从网络中提取数据,然后将其丢弃。
          • @user97693321。如何添加从 Web 服务解析的多个图像?
          【解决方案8】:

          由于我们现在在 IOS6 上,您不再需要将图像写入磁盘。
          从 iOS5 开始,您现在可以在 coredata 二进制属性上设置“允许外部存储”。 根据苹果的发行说明,它的含义如下:

          图像缩略图之类的小数据值可以有效地存储在 数据库,但大型照片或其他媒体最好直接由 文件系统。您现在可以指定托管的值 对象属性可以存储为外部记录 - 参见setAllowsExternalBinaryDataStorage: 启用后,Core Data 会启发式地根据每个值决定是否 它应该将数据直接保存在数据库中或将 URI 存储到 它为您管理的单独文件。您不能根据 如果使用此选项,则为二进制数据属性的内容。

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-05-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-05-15
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多