Displaying interlaced (progressive) Image in UIImageView

cocoa-touch, ios, iphone, objective-c, uiimageview

Solution

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.

Problem

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 image(just part of the data) and then display the full image in full quality. this is best shown in the VIDEO HERE I followed this SO question: How do I display a progressive JPEG in an UIImageView while it is being downloaded? but all I got was a imageview that is being rendered as data keeps comes in, no low-quality version first, no true progressive download and render. can anyone share a code snippet or point me to where I can find more info as to how this can be implemented in an iOS app ? tried this link for example which shows JPEG info, it identifies the image as progressive http://www.webpagetest.org/jpeginfo/jpeginfo.php?url=http://cetus.sakura.ne.jp/softlab/software/spibench/pic_22p.jpg and I used the correct code sequence ``` -(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); } } ``` but the code only shows the image when it is finished loading, with other images, it will show it as it downloading, but only top to bottom, no low quality version and then progressively add detail as browsers do. DEMO PROJECT HERE

Original source

Related problems