【问题标题】:Load low resolution image and progressive load of high resolution加载低分辨率图像和渐进式加载高分辨率
【发布时间】:2011-02-11 02:36:58
【问题描述】:

如何在页面上显示低分辨率图像,然后在第二次延迟后加载高分辨率版本?这是用图层完成的吗?线程?

【问题讨论】:

  • 我们需要更多信息。您是在谈论普通的 Objective-C 应用程序吗?还是 HTML 页面?您是否可以控制服务器上的图像数据?
  • cocoa-touch - ipad/iphone 应用

标签: iphone cocoa-touch ipad


【解决方案1】:

通常,此功能是通过以某些interlaced/progessive 模式保存的图像文件来实现的。这允许显示应用程序(即浏览器)在第一块数据到达时以低质量连续显示图像。可用的数据越多,图像的质量就越高。

此功能独立于网络服务器。只有客户端应用程序负责支持此模式

This site 展示了一些示例。

【讨论】:

    【解决方案2】:

    听起来您在描述 Three20 中的 TTPhotoViewController(用于 Facebook iPhone 应用程序)。当您第一次开始查看图像时,它只是一个被拉伸的缩略图。 “高分辨率”版本正在后台下载,下载完成后,它会替换现有的拉伸图像。

    【讨论】:

    • 在这种情况下,它是用线程完成的。最常见的做法是加载缩略图,分离一个线程开始下载大图,然后运行一个 self performSelectorOnMainThread:因为你需要在主线程中处理 UI。
    【解决方案3】:

    有几种选择:

    1) 以支持渐进式下载的格式(progressive JPEGinterlaced PNG)将图像保存在服务器上。我认为您必须为客户提供特殊支持,即。自己编写从PNG/JPEG到UIImage的图像解码部分,大概是使用一些库。

    2) 在服务器上的每个图像上保存一个小缩略图。当您要下载图像时,您首先要下载缩略图,进行简单的缩放以将其拉伸到完整的图像大小,同时下载完整版本。如果您真的想要花哨,可以有多个不同大小的缩略图。您将在服务器上拥有更多数据,但客户端代码应该相当简单。

    3) 也许您已经在客户端上拥有缩略图?在这种情况下,您可以在加载其余部分时将缩略图拉伸到完整图像大小以创建低分辨率版本。

    如果你问的是如何准确地编写第二个或第三个解决方案……你真的不需要显式线程,我不确定“层”在这种情况下是什么意思。从网络加载UIImage 非常简单,有点像这样:

     NSURL *url = [NSURL URLWithString:@"http://somewhere/foo.png"];
     NSURLRequest *request = [NSURLRequest requestWithURL:url];
     NSData *data = [NSURLConnection sendSynchronousRequest:request
        returningResponse:NULL error:NULL];
     UIImage *image = [UIImage imageWithData:data];
    

    您可以将此代码转换为函数,加载并显示缩略图,然后加载并显示完整图像。所有这些都可以在in background 完成,这样您就可以在数据加载时做一些事情。

    【讨论】:

    • 在主线程上加载同步请求会使其停止(这是一个糟糕的用户体验)并且在主线程上加载 UIImage 是不安全的(就像所有其他 UI* 类一样),所以- 不建议编写此代码。不过,在主线程中使用异步 NSURLConnection 是可以的。
    • 加载同步请求会阻塞当前线程,但正如我所写,您可以在后台运行整个代码。这样你就不会阻塞主线程,并且仍然可以使用简单的同步接口 NSURLConnection 而不是笨拙的回调。在后台线程中加载UIImage 是安全的,我自己使用这样的代码。
    【解决方案4】:

    我知道这篇文章已经过时了,但以防万一有人在寻找它,有一个名为 NYXImagesKit 的项目可以满足您的需求。

    它有一个名为NYXProgressiveImageView 的类,它是UIImageView 的子类。

    你所要做的就是:

    NYXProgressiveImageView * imgv = [[NYXProgressiveImageView alloc] init];
    imgv.frame = CGRectMake(0, 0, 320, 480);
    [imgv loadImageAtURL:[NSURL URLWithString:@"http://yourimage"]];
    [self.view addSubview:imgv];
    [imgv release];
    

    另外,一个不错的选择是将您的图像保存为interlaced,以便它以低质量加载并随着下载而改进。如果图像正常,则从上到下加载。

    【讨论】:

    • 你知道有没有其他类做同样的事情?这个类只支持 iOS 5 +.. 我需要它在 iOS 4.3 + 中工作
    【解决方案5】:

    我可以通过 afnetworking 下载。我使用了以下代码

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *filePath =  [[paths objectAtIndex:0] stringByAppendingPathComponent:@"tempPath"];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"yourUrl"]];
    
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];
    
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        self.actualImage = [UIImage imageWithData:[NSData dataWithContentsOfFile:filePath]];
    
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        [imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfFile:filePath]]];
        self.actualImage = [UIImage imageWithData:[NSData dataWithContentsOfFile:filePath]];
    
    }];
    
    [operation start];
    

    【讨论】:

      猜你喜欢
      • 2015-03-12
      • 2017-08-23
      • 2011-04-07
      • 1970-01-01
      • 2016-10-13
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多