首页 文章

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

提问于
浏览
10

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

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

这最好显示在VIDEO HERE

我跟着这个问题:

How do I display a progressive JPEG in an UIImageView while it is being downloaded?

但我得到的只是一个imageview,正在呈现数据保持,第一个没有低质量版本,没有真正的渐进式下载和渲染 .

任何人都可以共享一个代码段或指向我可以找到更多关于如何在iOS应用程序中实现这些信息的信息?

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

http://www.webpagetest.org/jpeginfo/jpeginfo.php?url=http://cetus.sakura.ne.jp/softlab/software/spibench/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 PROJECT HERE

5 回答

  • 3

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

    首先,您将需要一个JPEG解码库:libjpeg或libjpeg-turbo . 然后,您需要将其集成到可以与Objective-C一起使用的内容中 . 有一个开源项目使用这个库PhotoScrollerNetwork,它使用turbo库来解码非常大的jpegs "on the fly",因为它们可以进行平移和缩放(PhotoScroller是一个Apple项目,可以进行平移和缩放,但是它需要预先平铺的图像) .

    虽然上述项目并不完全符合您的要求,但您应该能够解除大部分libjpeg-turbo接口以解码渐进式图像并在接收到时返回低质量图像 . 看起来您的图像非常大,否则几乎不需要渐进式图像,因此您也可以找到上述使用项目的平移/缩放功能 .

    PhotoScrollerNetwork的一些用户请求支持渐进式图像,但似乎在网络上几乎没有使用它们 .

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

    在这种情况下,您将构建一个自己设计的二进制文件 - 一个在其中有4个图像的文件 . 前四个字节将提供其后的数据长度(并且每个后续图像将使用相同的4字节前缀) . 然后,在iOS端,随着下载开始,一旦你获得第一个图像的完整字节,你可以使用它们来构建一个小的低分辨率UIImage,并在接收下一个图像时显示它 . 当下一个完全到达时,您将使用较新的较高分辨率图像更新低分辨率图像 . 它可能你可以使用拉链容器,并在飞行减压 - 不是100%肯定 . 在任何情况下,以上都是您的问题的标准解决方案,并将提供与libjpeg几乎相同的性能,而工作少得多 .

  • 0

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

    这是一个与服务器协同工作的相机应用程序 . 所以这些图像来自iPhone的相机并远程存储 . 当服务器获取图像时,它会被处理(使用imageMagick,但可能是任何合适的库)并存储为3种尺寸 - 小拇指(~160 x 120),大拇指(~400x300)和全尺寸(〜双视网膜)屏幕尺寸) . 目标设备是视网膜iPhone .

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

    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 可能最终将小拇指,然后是大拇指,最后将全分辨率图像应用于单个imageView,具体取决于首先到达的图像 . 结果非常顺利 .

    这是gist showing the basic idea

    这可能不适合您,因为您可能无法控制进程的服务器端 . 在我实现这个之前,我正在寻求David H所描述的解决方案 . 一旦我意识到我还需要自己访问低分辨率图像,这本来会做得更多,而且效果不大 .

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

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

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

    update

    在推荐 NYXProgressiveImageView 之后,我意识到这就是你一直在使用的东西 . 不幸的是你没有在你的原帖中提到这一点,所以我觉得我已经有点蠢蠢欲动了 . 事实上,再次阅读你的帖子,我觉得你有点不诚实 . 从您的帖子的文本,看起来好像"DEMO"是您创建的项目 . 事实上你没有创建它,你从这里复制它:

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

    来自cocoaintheshell的this blog entry伴随您所做的唯一更改是一个NSLog行,并更改JPG测试URL . 您发布的代码段不是您的,它是从此项目复制而没有归属 . 如果你在帖子中提到了这一点,它会为我节省大量时间 .

    无论如何,回到帖子...当您使用此代码时,您可能应该使用当前版本,这是在github上:

    https://github.com/Nyx0uf/NYXImagesKit

    另见this blog entry

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

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

    接下来,您需要确保使用GOOD图像进行测试

    例如,这个PNG效果很好:

    http://www.libpng.org/pub/png/img_png/pnglogo-grr.png

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

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

    JPEG tempImage渲染似乎存在一个问题,我无法解决这个问题 - 也许你可以 . 这就是为什么"Demo"无法正常工作的原因 .

    更新2
    添加gist

  • 8

    我相信这就是你要找的东西:

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

    用于在iOS和OS X上下载和解码渐进式JPEG的框架,它使用libjpeg-turbo作为底层JPEG实现 .

  • 1
  • 0

    我有同样的问题然后我发现一些棘手的不正确的解决方案,但它的工作原理 .

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

    This is example for android我希望你能把它变成ios版本 .

相关问题