iOS で WebP を扱う上での注意点
iOS アプリ開発の仕事で WebP を使うことがあったのだが、そのときの体験談を話す。
そのアプリは画像ビュワーのようなもので、大量の(高解像度)画像をダウンロードして見るものである。
大量の画像(WebP)をダウンロードして一度にエンコードすると CPU 使用率がひどいことになるので、一度ディスクにWebPの形式のままキャッシュしておくのがよい。
必要に応じてエンコードするためにその画像データが WebP の形式かどうかを判定する方法がないかと模索したが、バイナリの先頭を見ることにした。画像フォーマットなんて決まってるしこれでいいですかね?
func isWebP(data: NSData) -> Bool {
var buffer = [UInt8](count: 4, repeatedValue: 0x00)
data.getBytes(&buffer, length: 4)
return buffer == [82, 73, 70, 70] ? true : false
}
画像のダウンローダーは SDWebImage を使用したが、
- ダウンロードと同時にエンコードが走る
- ダウンロード後にディスクだけに保存ができない(メモリとディスク両方なら可能)
この二つの理由から SDWebImage は WebP エンコードのためだけに使用し Alamofire をダウンローダーとして使った。
Alamofire.request(.GET, url).response { (request, response, data, error) in
if error != nil {
var imageData = data as? NSData
// 一度にエンコードすると重くなる
// var image = UIImage.sd_imageWithWebPData(imageData)
// save to disk code
}
}
まとめ
- 高解像度画像を一気にダウンロードしてエンコードすると CPU 使用率が高くなる
- SDWebImage(WebP 対応の画像ダウンローダー) は意外と融通が効かないので、一部自分で実装もしくは他のライブラリの力を借りた方が良い場合もある