ImageOptim

Case study: Tweetbot for iPad

Tweetbot (an excellent, graphically-rich iOS Twitter client) weights 33.4MB, of which over 26MB is used for 978 images. It has all images compressed with Xcode, which converted them to “CgBi” format.

Here are results of converting images back to PNG and optimizing them with ImageOptim and ImageAlpha:

Unoptimized: 50MB, Xcode: 26MB, ImageOptim: 17MB, ImageAlpha: 9MB

The chart represents image sizes. Each segment in each bar is one file. Files are ordered by their unoptimized size.

Unoptimized
RGBA image saved with vanilla libpng. That's a typical size you'd get from an image processing software such as Photoshop.
Xcode default
That's the size Tapbots delivered to the AppStore.
ImageOptim
Images dropped into ImageOptim 1.4.0 and optimized few times until optimization gave no more savings.
ImageAlpha+ImageOptim
Images converted to PNG8+alpha using ImageAlpha. Images that could not be converted without noticeable quality loss were posterized instead (using ImageAlpha's posterizer with dithering). After conversion images were further optimized with ImageOptim.

Loading speed

Although Xcode optimisation is assumed to improve decoding speed of PNG images, testing on an actual device disproves that: (benchmark details at the end)

Type of imageXcode compressionUIImageView creationUIImageView displayBitmap access time
Xcode BGRA/CgBiEnabled8.6s11.7s12.8s
ImageOptimDisabled1.2s5.4s6.4s
ImageAlpha+ImageOptimDisabled1.2s4.7s4.7s

Xcode-optimized images were significantly slower to display. Decoding speed appears to be correlated to image file size more than anything else (most likely savings on byteswapping are negligible compared to additional disk I/O and extra data to decompress.)

Conclusion

Although Xcode image compression is better than nothing, the “CgBi” images are larger and slower than well optimized, standard PNGs.

Disabling Xcode conversion and simply using ImageOptim instead was enough to reduce the application size by almost 30% (33.4MB down to 23.8MB) and halve initial display time in the benchmark.

Manually optimizing images with ImageAlpha reduced entire application size by more than a half (33.4MB down to 16.3MB). Images alone were 65% smaller and were displayed 2.5 times quicker than Xcode-optimized ones.

Since Xcode conversion can be disabled and iOS supports standard PNGs, such big size and speed savings are possible in actual AppStore applications.

Information about tests

All ImageOptim optimizations were lossless.

57% of images in the ImageAlpha set were optimized losslessly. Average similarity (measured in DSSIM metric, using alpha-channel-aware tool) was 0.999. 98% of images had DSSIM better than 0.99 (equivalent of 95% quality JPEG). Worst DSSIM was 0.97 (equivalent of 80% quality JPEG).

Benchmark ran on 3rd generation iPad with iOS 5.1. Single view application with ARC. Numbers are in seconds, average of 3 runs (app restarted each run). The following code has been ran in a loop for all 492 image names: Bitmap access: CGRelease(CGDataProviderCopyData(CGImageGetDataProvider([[UIImage imageNamed:names[i]] CGImage]))); UIImageView creation: [self.window addSubview:[[UIImageView alloc] initWithImage:[UIImage imageNamed:names[i]]]]. Display time measured until the main thread runs first dispatch_async() after didFinishLaunchingWithOptions which executed the benchmark.

Update: there's an independent benchmark which confirms that file size is the most important factor (red bars), that pixel format in the compressed image doesn't matter (YCbCr JPEGs load faster than Xcode's BGRA) and also shows that rendering speed is the same regardless of format used (green bars) [except one odd case on iPhone 3G].

Other ImageAlpha+ImageOptim successes

IncrediBooth reduced from 70MB to 31MB.

Joseph J Schmitt: we dropped around 9 MB from @vimeo's .ipa size by using ImageOptim. Made the retina update a wash.

David Jones: Managed to reduce @acerider_game’s binary size from 40.4MB to 26.6MB by using ImageAlpha and then ImageOptim. Thanks @pornelski

WASTED app analyzer will show you how much you can save.