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

Ios 在UIImageView中显示隔行扫描(逐行扫描)图像,ios,iphone,objective-c,cocoa-touch,uiimageview,Ios,Iphone,Objective C,Cocoa Touch,Uiimageview,我试图在下载时显示一个JPEG图像,使用部分数据,类似于许多网络浏览器或facebook应用程序 图像存在低质量版本(仅部分数据),然后以全质量显示完整图像 这在下面的示例中得到了最好的展示 我接着问了这个问题: 但我得到的只是一个图像视图,它随着数据的进入而呈现,没有低质量的版本,没有真正的渐进式下载和呈现 有谁能分享一段代码片段,或者告诉我在哪里可以找到更多关于如何在iOS应用程序中实现这一点的信息吗 例如,尝试了显示JPEG信息的链接,它将图像标识为渐进式 我使用了正确的代码序列 -(

我试图在下载时显示一个JPEG图像,使用部分数据,类似于许多网络浏览器或facebook应用程序

图像存在低质量版本(仅部分数据),然后以全质量显示完整图像

这在下面的示例中得到了最好的展示

我接着问了这个问题:

但我得到的只是一个图像视图,它随着数据的进入而呈现,没有低质量的版本,没有真正的渐进式下载和呈现

有谁能分享一段代码片段,或者告诉我在哪里可以找到更多关于如何在iOS应用程序中实现这一点的信息吗

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

我使用了正确的代码序列

-(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);
    }
}
但代码仅在加载完成后显示图像,与其他图像一起,它将在下载时显示图像,但只显示从上到下,没有低质量的版本,然后像浏览器那样逐步添加细节


这是一个我感兴趣了一段时间的话题:使用苹果的API似乎没有办法做你想做的事情,但如果你能在这方面投入时间,你可能会让它发挥作用

首先,您需要一个JPEG解码库:libjpeg或。然后,您需要将其集成到Objective-C中。有一个开源项目使用此库,它利用turbo库在下载时“动态”解码非常大的JPEG,以便对其进行平移和缩放(PhotoScroller是苹果公司的一个项目,负责平移和缩放,但它需要预平铺图像)

虽然上面的项目并不完全是您想要的,但是您应该能够提升大部分libjpeg turbo接口来解码渐进式图像,并在接收到低质量图像时返回它们。您的图像看起来相当大,否则就不需要渐进式图像,因此您可能会发现平移/缩放上述使用项目的ng能力

PhotoScrollerNetwork的一些用户要求支持渐进式图像,但似乎它们在web上的通用性很低

编辑:第二个想法:如果是你的网站,你会用它来出售渐进式图像(我认为这是因为通常很少能找到),你可以采取完全不同的策略


在本例中,您将构建一个自己设计的二进制文件,其中包含4个图像。前四个字节将提供其后数据的长度(并且每个后续图像将使用相同的4字节前缀)。然后,在iOS端,当下载开始时,一旦您获得第一个映像的完整字节,您可以使用这些字节构建一个小的低分辨率UIImage,并在接收下一个映像时显示它。当下一个映像完全到达时,您将用更新的高分辨率映像更新低分辨率映像。您可以使用zip容器and执行动态解压缩-不是100%确定。无论如何,上述是解决您问题的标准解决方案,可以提供与libjpeg几乎相同的性能,而且工作量要少得多。

尝试一下,可能对您有用:


我为目前正在使用的应用程序实现了渐进式加载解决方案。它不使用渐进式Jpeg,因为我需要更大的灵活性来加载不同的res版本,但我得到了相同的结果(而且效果非常好,绝对值得实现)

这是一个与服务器协同工作的摄像头应用程序。因此,图像来源于iPhone的摄像头,并远程存储。当服务器获取图像时,它会被处理(使用imageMagick,但可以是任何合适的库),并以3种尺寸存储-小拇指(~160 x 120)、大拇指(~400x300)和全尺寸(~2倍视网膜屏幕尺寸).目标设备是iPhone

我有一个ImageStore类,负责从任何位置异步加载图像,首先尝试最快的位置(实时缓存、本地文件系统缓存、资产库、网络服务器)

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

因此
FULLSIZEMAGEFROMPATH

将获取完整版本,并调用
largeThumbImageFromPath

largeThumbImageFromPath

将获取大拇指并从路径调用
smallThumbImageFromPath

smallThumbImageFromPath

只会得到一个小拇指

这些方法调用包装在可取消NSOperations中的调用。如果较大的res版本在其任何较低res同级之前到达,则相应的较低res调用将被取消。最终结果是
fullsizeImageFromPath
可能会应用小thumb,然后是大thumb,最后是完整res图像到s单个图像视图取决于哪个先到达。结果非常平滑

这是一个

这可能不适合您,因为您可能无法控制流程的服务器端。在我实现这一点之前,我一直在追求David H所描述的解决方案。如果我意识到自己也需要访问低分辨率图像,那么这将是更多的工作,也没有多大用处

另一种可能更接近您的需求的方法被解释

这已经演变为
NYXProgressiveImageView
,UIImageView的一个子类,作为

最后…对于一个真正的黑客解决方案,您可以使用UIWebView显示渐进式PNG(渐进式JPEG似乎不受支持)

更新

在推荐了
NYXProgressiveImageView
之后,我意识到这就是您一直在使用的
  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;
NYXProgressiveImageView.h
NYXProgressiveImageView.m
NYXImagesHelper.h
NYXImagesHelper.m
/// Note: Progressive JPEG are not supported see #32