CUIからjpgやpngの画像をAVIFに変換できる「cavif」入門

Writer:松岡宗谷松岡宗谷
Posted date:

日の目を見なかった最新画像フォーマットのAVIFですが、2021年になってようやくGoogelトレンドにも載るようになってきました。エンジニアを中心に注目は徐々に浴びつつあるようです。

そんなAVIFですが、現時点では対応しているソフトウェアは少なくブラウザの対応自体も多岐に渡っているという状態ではありません。しっかりとサイト運営をしていくにあたって、最新画像フォーマットに対応したいところですが、現状ではエンジニアの力を借りてjpgやpngなどの主要画像をAVIFに変換する事がベストな状況でございます。

今回はそんな要望に完全に答える「cavif」と言うRUST言語のライブラリ入門として書かせて頂きます。

    目次

  • はじめに
  • AVIFとは
  • ブラウザのAVIF対応状況
  • 純度100%Rustで実装された「cavif」とは
    • ちなみに・・・「cavif」ってなんて読むんでしょ。個人的には『キャビフ』って読んでます
  • CUIからjpegやpngの画像をAVIFに変換できる「cavif」をインストールしよう
    • 「cavif」をインストールする前に必要最低限な環境の準備
      • 必要最低限な環境・概要
      • wgetのインストール
      • Perlのインストール
      • gitのインストール
      • makeのインストール
      • Rustのインストール
      • Rustのパスを通す
      • gccのインストール
      • nasmのインストール
  • 「cavif」のインストール
  • 画像の準備
  • 「cavif」の使い方
  • 「cavif」のオプション
  • 理想のcavifコマンド
  • 「cavif」で変換した生成されたAVIFフォーマットの参考画像
  • 【番外編】サーバーではどのくらい変換が早くなるかの検証
    • CPU:2Core メモリ:1GBの場合
    • CPU:12Core メモリ:32GBの場合
  • まとめ
  • 参考にしたサイト・記事

はじめに

とは言ってもRust言語(ちなみにラストって読みます)ってなんだよという所からつまずく方がいらっしゃる事が多いと思われます。PHPやPythonなどと違ってインストールするだけでも大変な言語となっており仕様自体も難易度が高いのですが、何とかコマンドラインを叩くだけで実際に「cavif」を使って画像変換する所まではだだーっと書かせて頂きます。細かい事は理解しなくても良いのでお付き合いくださいませ。

AVIFとは

AV1 Image File Format(AVIF)は、画像や画像シーケンスをAV1で圧縮してHEIFファイル形式で保存するための画像ファイルフォーマットの仕様です。圧縮にAV1ではなくHEVCを使用しているようです。

なんと言ってもAVIFはHDRカラーをサポートしてアルファチャンネルやアニメーションにも対応できる所が強いと個人的には感じます。

圧縮率に関しても

100kbのjpgがあれば

webpが30kb

AVIFは18〜25kbあたりまで圧縮可能です。

ですが、変換速度は恐ろしく遅いです。

非現実的なまでに低速であることが欠点とされている所に関しては要注意ですね。

開発者 Alliance for Open Media

初版 2018年3月28日

バージョン1.0.0は、2019年2月19日に策定。

ブラウザのAVIF対応状況

引用元:https://caniuse.com/?search=AVIF

全体で62%となっています。現時点ではChromeとAndroidが対応しておりますが、普及率を考えるとまだまだと言った所ですね。iOSのsafariが対応すれば一気に広がりそうです。

純度100%Rustで実装された「cavif」とは

jpgやpngの画像を拡張子.「AVIF」に変換できるRust製のライブラリツールです。

エンジニア視点で申し訳ないですが、注目はなんと言ってもピュアなRUSTで書かれてる所です。

他のライブラリは大体C言語のライブラリを介して作られているのですが、この「cavif」は完全なる1言語で完結してるのがすごいですので皆さん使ってみてください。

「cavif」の現時点での最新バージョンは1.0.0(2021年3月24日リリース)です。

ようやくメジャーバージョンになったようですので、まだまだ機能面では薄いと感じる人もいらっしゃるかと思われますが、実際に1.0.0リリース初日に使い倒してみた所、バグはなかったので安心して利用できます。

kornelski/cavif-rs - github

https://github.com/kornelski/cavif-rs

作者のKornelさん - github

https://github.com/kornelski

作者のKornelさんのサイト

https://kornel.ski

経歴を見るだけでも1エンジニアから見ると伝説の人って感じですね。同じ人間なんかな?

ちなみに・・・「cavif」ってなんて読むんでしょ。個人的には『キャビフ』って読んでます

現時点で日本の記事は皆無ですのでなんて読めば良いか悩んでますが

個人的にはキャビフ!これに一票です。

CUIからjpegやpngの画像をAVIFに変換できる「cavif」をインストールしよう

前置きが長くてすいません。ここからようやく実際にインストールしていきますが、Rustの仕様上と言うかRustのcargoコマンドの仕様上初心者殺しの罠がありまくるのでその説明をすると大変です。

入門という事でそこの説明は省きますね。

順番にコマンドを叩いていけばエラーを起こさずに正常にインストールできるようにしました。

「cavif」をインストールする前に必要最低限な環境の準備

ですが、まずは必要最低限な環境の準備について説明させて頂きます。

必要最低限な環境・概要

  • サーバーに関してはできるだけ最新のバージョンを選ぶ

    今回はCentOSのStream8にて実際にインストールしてAVIFに変換致しました。

  • sshでログインしてターミナルを開ける環境をお願い致します
  • GCPなどのデフォルトでrootログインできない場合はsudoで押し通して下さい。
  • インストールする順序も重要ですので1つも飛ばさずに確実にインストールして下さい。
  • 時折、パスが通ってるかのチェックをしていますのでパスが通ってなかったら通してから次に進んで下さい。

wgetのインストール

dnf install wget

Perlのインストール

dnf install perl

gitのインストール

dnf install git

makeのインストール

dnf install make

Rustのインストール

curl https://sh.rustup.rs -sSf | sh

Rustのパスを通す

export PATH="$HOME/.cargo/bin:$PATH"

# v確認でパスが通ってるかチェック
rustc --version
cargo --version

gccのインストール

dnf install gcc

nasmのインストール

# nasmダウンロード
wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.gz
↓
# 解凍
tar xvfz nasm-2.15.05.tar.gz
↓
# 移動
cd nasm-2.15.05
↓
# configure実行
./configure
↓
# コンパイル
make
↓
# nasmインストール
make install
↓
# v確認でパスが通ってるかチェック
nasm --version

「cavif」のインストール

ようやくここでメインの「cavif」のインストールを開始します。実はこのライブラリ関連するライブラリ等が130も必要なので恐ろしく時間がかかります。特にGCPの安いサーバーを借りると鬼のような待ち時間になりますが、バグってたり、フリーズしてたりではないので安心して下さい。(5分10分かかるかも?)

conohaのVPSなら安いサーバーでも結構早くインストールできます(2分、3分)。

cargo install cavif

画像の準備

ようやくインストールが完了しましたら、変換する画像をダウンロードしましょう。今回はResizeCDNが変換で使用する画像を用意致しましたので、こちらをダウンロードして変換致しましょう。

もちろん、別途で用意しても構いません。

# 元のディレクトリに移動
cd ..
# 変換する画像をダウンロード
wget https://resizecdn.com/assets/img/media/article/14.png
wget https://resizecdn.com/assets/img/media/article/15.jpg

「cavif」の使い方

基本的にはこれだけです。シンプルイズベストですね。

cavif 14.png

「cavif」のオプション

v.1.0.0の割に結構オプションも豊富でサービスに組み込む最低限の機能は実装されております。

--quality=n
画質を1から100の間で表し、デフォルト値は80です。数字はJPEGの品質尺度とは異なる意味を持っています。コーデックを比較する際には注意が必要です。可逆圧縮には対応していません。

--speed=n
エンコードの速度を、1から10の間で設定します。(数値が低いほど遅い)デフォルト値は1です。AVIFのエンコードはかなり遅いので気を付けましょう。ResizeCDN的には2か3をオススメします。

--overwrite
すでに .avif が存在する場合、ファイルを置き換えます。デフォルトでは既存のファイルはそのまま残されます。

-o path
同じ名前.avifではなく、指定したパスに書き込みます。複数の入力ファイルが指定されている場合はディレクトリとして解釈されます。

--quiet
変換中に何も表示しません。

--premultiplied-alpha
半透明の色の品質を下げることで、透明な画像の圧縮を改善することができます。警告: 新機能なので、まだすべてのデコーダと互換性がないかもしれません。

--dirty-alpha
透明なピクセルのRGB値を変更しません。デフォルトでは空間の浪費を避けるために透明なピクセルの無関係な色はクリアされます。

--color=rgb
YCbCr色空間ではなくRGB色空間を使ってエンコードします。色をロスレスに近づけることができますがファイルサイズが大きくなります。

理想のcavifコマンド

色々試した結果、qualityに関しては50くらいがベストで

speedに関しては2か3がベストで

overwrite(置き換え)に関しては必須の設定で

# 理想のcavifコマンド
cavif --quality=50 --speed=2 --overwrite 14.png

結論としてはこのコマンドが理想の形だと思われます。

「cavif」で変換した生成されたAVIFフォーマットの参考画像

Before After

144KB→10KB

単色で塗られている画像+透過だとどうなるかという意図でこの画像を変換致しました。quality=50で変換致しましたが、少々色が変っちゃいますね。原本を見てなければ劣化しているとは気付きにくいですが、比べるとやはりqualityの調整は必要そうです。にしても圧縮率やば。


Before After

534KB→320KB

ぱっと見の印象としてはほぼ変わらず、少々色味が抜けている?感じでしょうか。意図としては黒系と似た色同士の周りがいかに劣化するかを確認するためにライオンの画像を選びました。こちらもやはり比べているからわかるものの並んでなかったら劣化には気づかない程度でサイズはかなりスリム化した印象です。

【番外編】サーバーではどのくらい変換が早くなるかの検証

CPU:2Core メモリ:1GBで構築して変換していたんですが、いかんせん遅い。遅すぎてどうなってるんだと思いCPU:12Core メモリ:32GBのサーバーも借りてどの程度変わるのか検証を行いました。

【検証画像】

# 144KB

14.png

# 534KB

15.jpg

CPU:2Core メモリ:1GBの場合

# 6秒
cavif --quality=50 --speed=2 --overwrite 14.png

# 53秒
cavif --quality=50 --speed=2 --overwrite 15.jpg

CPU:12Core メモリ:32GBの場合

# 1.2秒
cavif --quality=50 --speed=2 --overwrite 14.png

# 8秒
cavif --quality=50 --speed=2 --overwrite 15.jpg

シンプルに変わりますね。個人で使うのかサービスとしてガッツリ使うのかで賛否分かれると思いますが、サービスとして導入するなら最低でもCPU:8Core メモリ:16GB以上の性能がないとお話にならないなーというくらい変換に時間がかかります。

まとめ

いかがだったでしょうか?「cavif」を使用すればソフトウェアに頼らずともなんならAVIF変換のソフトウェアを開発する事も可能となります。

1つ1つを変換するのは現実的ではないので実際にはcronなどを利用して変換していくのがベストプラクティスなのではないでしょうか。その際にはオプションの --overwrite は外した方がいいかもしれませんね。

実はこの他にも全てのAVIF変換できるライブラリやツールを試しました。

現時点ではC、Rust、Go、nodejsあたりでライブラリがありました。時間と共にWebと親和性の高いPHPでも実装(非公式ライブラリで)されるとは思いますが、いかんせん変換時間が長いので公式としては実装はないかもしれません。

かなり足早にコマンドの詳細説明がないままにここまで来ましたが、おそらく「cavif」をちゃんとインストールできたのではないでしょうか?変換効率との相談になるかと思われますが、結果が良ければぜひ運営しているサイトやサービスにAVIFを導入して下さい。

では、以上で

CUIからjpgやpngの画像をAVIFに変換できる「cavif」入門 の締めとさせて頂きます。

ではではー。

参考にしたサイト・記事

kornelski/cavif-rs - github

https://github.com/kornelski/cavif-rs

Rustプログラミング言語

https://www.rust-lang.org/ja

rustup.rs - The Rust toolchain installer

https://rustup.rs

NASM

https://www.nasm.us

ソースからNASMをインストールする

https://noknow.info/it/os/install_nasm_from_source

ResizeCDNを利用して画像の悩みを一気に解決しませんか?
  1. 圧縮はもちろん最新画像フォーマットにも対応
    ResizeCDNを利用すると圧縮・最新画像フォーマットに自動対応して配信できます。
  2. 全体対応・特定の箇所のみと柔軟なCDN配信が可能
    プッシュ型ならでは柔軟な対応とハイスピード最短1分でCDN化ができます。
  3. →より詳しく

著者プロフィール
松岡宗谷

画像特化型CDNサービス ResizeCDN https://resizecdn.com/ を開発・運営しています。スペースナビ 代表取締役。スタートアップ界隈でCTO→Sharetube創業→スペースナビ創業→画像に特化したCDN開発。個人の夢は完全義体化。会社の夢は宇宙事業。プログラマーは死ぬまで現役でありたい

Twitter:@mtoksuy