How to display WebP images on iOS using Swift

Build the WebP framework

You can get a script to build the WebP framework from Carson McDonald

Change the script to use the latest stable version of the WebP code. Download the source code of WebP library as a tar.gz file (it is what the scrip;t requires). The download link is near the middle of the page.  Run the script and place the resulting framework into your project.

Even though it is easy to compile the WebP library, the script is nice in that it compiles all the libraries needed for each iOS platform and the simulator and puts it all in a nice framework for you. Awesome job Carson.

Add the WebP Header to your bridging header

    #import "WebP/decode.h”


You can create a bridging header by creating a header file in your project (select File/New/File in Xcode’s menu,  select  iOS/Sources and the  Heder File icon, hit Next, then name it and Create it).

In the projects build setting for your target, add the path to your header file. Edit the Objective-C Bridging Header field (search on bridg 😄) , add the path of the header (e.g. DisplayWebP/DisplayWebP-Bridging-Header.h).

Here’s the swift code you are looknig for:

import UIKit

private func freeImageData(info: UnsafeMutablePointer<Void>, data: UnsafePointer<Void>, size: Int) {
    free(UnsafeMutablePointer<Void>(data))
}

extension UIImage {
    class func imageFromWebPData(imagData: NSData) -> UIImage? {
        var width: Int32 = 0
        var height: Int32 = 0

        if WebPGetInfo(UnsafePointer<UInt8>(imagData.bytes), imagData.length, &width, &height) == 0 {
            return nil
        }
        let data = WebPDecodeRGBA(UnsafePointer<UInt8>(imagData.bytes), imagData.length, &width, &height)

        let provider = CGDataProviderCreateWithData(nil, UnsafePointer<Void>(data), Int(width * height) * 4, freeImageData)
        let colorSpaceRef = CGColorSpaceCreateDeviceRGB()

        let bi = CGBitmapInfo(rawValue: CGBitmapInfo.ByteOrderDefault.rawValue | CGImageAlphaInfo.Last.rawValue)

        let imageRef = CGImageCreate(Int(width), Int(height), 8, 32, 4 * Int(width), colorSpaceRef, bi, provider, nil, true, .RenderingIntentDefault)
        if imageRef == nil {
            return nil
        }
        return UIImage(CGImage: imageRef!)
    }
}


To decode a WebP image it is basically two lines: get the image info and then decode. Everything after the WebPDecodeRGBA function is to convert the decoded raw memory to an UIImage.

Usage

I typically use it after downloading an image using the resulting NSData:

        var image = UIImage(data: data)
        if image == nil {
            image = UIImage.imageFromWebPData(data)
        }


Demo code on GitHub

Sample code is provided on my GitHub. Check it out. 😄 The code also shows how to simply download images in the background and display them in a UICollectionView.

Documentation

Google's WebP Documentation

Good luck with your app.

smiceli@smiceli.com