post Image
WWDC17で新しく発表された画像フォーマットHEIFを使ってみた

HEIFとは

HEIFとはHigh Efficiency Image File Formatの略でMPEGよって開発された画像フォーマットの標準規格です。ちなみにヒーフと呼ぶ場合が多いようです。iOS11から公式にサポートされ、JPEG以上の圧縮率深度情報透過処理タイル化アニメーションなどJPEGにはなかった機能や改善点がある新しい画像フォーマットです。JPEGなどとの詳しい差分はwikiに載っています。

H.265/HEVCとは

まずHEIFを語る上で避けて通れない事として、H.265/HEVC(High Efficiency Video Coding)があります。ISO/IECのMPEGとITU-TのVCEGによる研究開発チームJCT-VC によって提案され、ITU-Tは2013年に承認されました。

HEIFはHEVCのコーデックが選択可能(というかこれ以外ありえない?)でHEIFとHEVCの違いはなんとなくでも理解しておきましょう。

Working with HEIF and HEVCによると
HEVCのエンコードは以下の環境でエンコード可能で

iOS
Hardware Encode A10 Fusion chip(iPhone7iPhone7 Plus
Software Encode 無理

逆にデコードに関しては

iOS
Hardware Decode A9 chip(iPhone6siPhone6s Plus)以上
Software Decode All iOS Devices

の端末で読み込む事が可能です。
なんか動かねーぞという場合には以上の内容を参考にしてください。
あっあともちろんiOS11以上でAPIは使用可能です

実際にHEIFを作成するには

HEIFを作成するには大まかに2つの方法があって、

  1. iPhone7, iPhone7 Plus, macOSのAPIを用いてエンコードする
  2. FFmpegNokiaのHEIFの実装を利用する

正直1.は研究段階ならともかく現実的ではないので2.を選択するのが無難だと思います。

FFmpegはHomebrewからインストールできます。

1. H.265/HEVCのエンコーダーが必要なのでまず以下のコマンドを入力します

brew install x265

2. FFmpegをオプションをつけてインストールします

brew uninstall ffmpeg
brew install ffmpeg --with-x265

3. NokiaのHEIFの実装をビルドします

git clone https://github.com/nokiatech/heif.git
cd heif
cmake .
make

4. FFmpegを用いてJPEGやPNGをHVECのbytestreamに変換します

crfは画像のQualityなのでスケールの範囲は0から51で、0ではLossless、23がデフォルト、51は最低です。 より小さい値でよりよい画質となります。
(追記)どうやらH.264ドキュメントを見ていたようです、@yohhoy さんの通りなので、間違えのないように

ffmpeg -i ./your-image.png -crf 12 -preset slower -pix_fmt yuv420p -f hevc bitstream.265

5. configファイルを作成します

詳しい内容はwikiのリンクで説明してありますので、こちらをどうぞ。HEIFは画像の中にサムネイルの情報を入れることができるのですが、今回は必要ないので除外してます(あってるのかな?)。

{
    "general": {
        "output": {
            "file_path": "output.heic"
        },
        "brands": {
            "major": "mif1",
            "other": ["mif1", "heic", "hevc"]
        }
    },
    "content": [{
        "master": {
            "file_path": "./path-to/bitstream.265",
            "hdlr_type": "pict",
            "code_type": "hvc1",
            "encp_type": "meta"
        }
    }]
}

6. 3でビルドした実行ファイルに5で作成したconfig.jsonを指定して実行します。

./Bins/writerapp ./path/to/config.json

作成したHEIFファイルの中身はHEIFのブランチ gh-pagesで確認することができます。

iOSでHEIFを読み込むには

iOSでローカルのHEIFファイルを読み込むには以下のコードを書きます。

// Read a jpeg image from file

let inputURL = URL(fileURLWithPath: "/tmp/image.heic")

if let source = CGImageSourceCreateWithURL(inputURL as CFURL, nil) {
    let image = CGImageSourceCreateImageAtIndex(source, 0, nil)
    // set image
}

ちなみにHEIFファイルがWEB上にある場合には

let inputURL = URL(string: "https://../image.heic")

// 何かのダウンローダー
downloader.download(url: inputURL) { (data: Data?, error: Error) in
    if let data = data, let source = CGImageSourceCreateWithData(data as CFData, nil) {
        let image = CGImageSourceCreateImageAtIndex(source, 0, nil)
        // set image
    }
}

でっ実際どれくらい圧縮されんのよ

記事の一覧を表示するための192×192のサムネイル画像を30個ほど圧縮してみましたが、JPEGと比べると15~20%近く合計で圧縮されていました。
画像サイズはffmpegのQualityのオプションによって上下すると思うので、一概には言えませんがWebPとも遜色ない圧縮率です。

HEIF最高や!!WebPなんて最初っからいらんかったんや!!

実験はiPhone 7Plusで行いましたが、デコード時間もハードウェアアクセラレーションを使っているおかげもあるのか、違和感なく表示されていました。

最後に

今回調べる上で技術的なドキュメントやWebの資料が少ないので、多少苦労しました。とくにHEVCなどのコーデック周りは専門家がいたほうがやりやすいと思います。何か情報クレ…クレメンス…。

自分たちが作っているアプリの要件やサポートOSや運用なども含めて、今後導入するかどうかを検討するといいと思います。

(追記)HEVC及びHEIFのエンコーダには特許の問題がありffmpegなどを使用した実用化は難しいです。現状iPhoneでしかHEIFのエンコードが不可能なので、サーバサイドでの作成は将来に期待しましょう。


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。