Displaying interlaced (progressive) Image in UIImageView

后端 未结 5 1884
南方客
南方客 2021-02-14 05:51

I am trying to display a JPEG image as it downloads, using part of the data, similiar to many web browsers do, or the facebook app.

there is a low-quality version of the

相关标签:
5条回答
  • 2021-02-14 06:08

    Try it, may be its useful for you :

    https://github.com/path/FastImageCache

    https://github.com/rs/SDWebImage

    0 讨论(0)
  • 2021-02-14 06:21

    I have the same problem then i found something tricky its not proper solution but it works.

    You have to load low resolution/thumbnail image when loaded then load actual image.

    This is example for android i hope you can transform it into ios version.

    0 讨论(0)
  • 2021-02-14 06:26

    I believe this is what you are looking for:

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

    A framework for downloading and decoding progressive JPEGs on iOS and OS X, that uses libjpeg-turbo as underlying JPEG implementation.

    0 讨论(0)
  • 2021-02-14 06:34

    I have implemented a progressive loading solution for an app I am currently working on. It does not use progressive Jpeg as I needed more flexibility loading different-res versions, but I get the same result (and it works really well, definitely worth implementing).

    It's a camera app working in tandem with a server. So the images originate with the iPhone's camera and are stored remotely. When the server gets the image, it gets processed (using imageMagick, but could be any suitable library) and stored in 3 sizes - small thumb (~160 x 120), large thumb (~400x300) and full-size (~ double retina screensize). Target devices are retina iPhones.

    I have an ImageStore class which is responsible for loading images asynchronously from wherever they happen to be, trying the fastest location first (live cache, local filesystem cache, asset library, network server).

      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;
    

    Each of these methods will also attempt to load lower-res versions. The completion block actually loads the image into it's imageView.

    Thus
    fullsizeImageFromPath
    will get the fullsized version, and also call largeThumbImageFromPath
    largeThumbImageFromPath
    will get the large thumb and also call smallThumbImageFromPath
    smallThumbImageFromPath
    will just get the small thumb

    These methods invoke calls that are wrapped in cancellable NSOperations. If a larger-res version arrives before any of it's lower-res siblings, those respective lower-res calls are cancelled. The net result is that fullsizeImageFromPath may end up applying the small thumb, then the large thumb, and finally the full-res image to a single imageView depending on which arrives first. The result is really smooth.

    Here is a gist showing the basic idea

    This may not suit you as you may not be in control of the server side of the process. Before I had implemented this, I was pursuing the solution that David H describes. This would have been a lot more work, and less useful once I realised I also needed access to lower-res images in their own right.

    Another approach which might be closer to your requirements is explained here

    This has evolved into NYXProgressiveImageView, a subclass of UIImageView which is distributed as part of NYXImagesKit

    Finally ... for a really hacky solution you could use a UIWebView to display progressive PNGs (progressive JPegs do not appear to be supported).

    update

    After recommending NYXProgressiveImageView, I realised that this is what you have been using. Unfortunately you did not mention this in your original post, so I feel I have been on a bit of a runaround. In fact, reading your post again, I feel you have been a little dishonest. From the text of your post, it looks as if the "DEMO" is a project that you created. In fact you didn't create it, you copied it from here:

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

    which accompanies this blog entry from cocoaintheshell The only changes you have made is one NSLog line, and to alter the JPG test URL. The code snippet that you posted isn't yours, it is copied from this project without attribution. If you had mentioned this in your post it would have saved me a whole heap of time.

    Anyway, returning to the post... as you are using this code, you should probably be using the current version, which is on github:

    https://github.com/Nyx0uf/NYXImagesKit

    see also this blog entry

    To keep your life simple, you only need these files from the project:

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

    Next you need to be sure you are testing with GOOD images

    For example, this PNG works well:

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

    You also need to pay attention to this cryptic comment:

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

    There seems to be an issue with JPEG tempImage rendering which I haven't been able to work out - maybe you can. That is the reason why your "Demo" is not working correctly, anyway.

    update 2
    added gist

    0 讨论(0)
  • 2021-02-14 06:35

    This is a topic I've had some interest in for a while: there appears to be no way to do what you want using Apple's APIs, but if you can invest time in this you can probably make it work.

    First, you are going to need a JPEG decoding library: libjpeg or libjpeg-turbo. You will then need to integrate it into something you can use with Objective-C. There is an open source project that uses this library, PhotoScrollerNetwork, that uses leverages the turbo library to decode very large jpegs "on the fly" as they download, so they can be panned and zoomed (PhotoScroller is an Apple project that does the panning and zooming, but it requires pre-tiled images).

    While the above project is not exactly what you want, you should be able to lift much of the libjpeg-turbo interface to decode progressive images and return the low quality images as they are received. It would appear that your images are quite large, otherwise there would be little need for progressive images, so you may find the panning/zooming capability of the above project of use as well.

    Some users of PhotoScrollerNetwork have requested support for progressive images, but it seems there is very little general use of them on the web.

    EDIT: A second idea: if it's your site that you would use to vend progressive images (and I assume this since there are so few to be found normally), you could take a completely different tact.

    In this case, you would construct a binary file of your own design - one that had say 4 images inside it. The first four bytes would provide the length of the data following it (and each subsequent image would use the same 4-byte prefix). Then, on the iOS side, as the download starts, once you got the full bytes of the first image, you could use those to build a small low res UIImage, and show it while the next image was being received. When the next one fully arrives, you would update the low res image with the newer higher res image. Its possible you could use a zip container and do on the fly decompression - not 100% sure. In any case, the above is a standard solution to your problem, and would provide near-identical performance to libjpeg, with much much less work.

    0 讨论(0)
提交回复
热议问题