アニメーション WebP の作り方

1. WebPとは?

Googleが開発している静止画像フォーマット です。

特徴としては、高圧縮率、アルファチャンネル可、アニメーション可能、と言ったところです。

アニメーションできる画像形式としては animated gif とか APNG とかもありますが、クオリティとファイルサイズと将来性の面で WebP が有利かなと思う次第です。 (主要なOS・ブラウザは対応している)

本記事では、アニメーション WebP の作り方を解説します。

2. 何でアニメーションを作ればいい?

アニメーション制作ツールは何でもいいですが、最終的に「連番 PNG ファイル」に出力できる物を使ってください。 筆者は After Effects が良いと思います!

3. 何で変換するの?

「アニメ画像に変換する君」

Microsoft Store でダウンロード(無料)

ググると良く紹介されているツールですが、大きなサイズかつフレーム数が多いと上手く動かなかったです。 試しに 1080p 60fps で 7 秒間くらいのアニメーションを読み込ませて変換に掛けたら、永遠に終わりませんでした。

小さくて短いものなら大丈夫っぽい。 とりあえず今回は不採用。

Google Official WebP Tools (Windows版)

Googleのサイトでダウンロード(無料)

CLI ですが、オフィシャル物だから一応変換できます ・・・と、思うじゃん?

コマンドラインで、連番 PNG ファイルをワイルドカード指定できません。 従って、連番になっている全てのファイル名をコマンドラインオプションで列挙しなければなりません。 コマンドラインには文字数制限があるので、400個くらいあるファイルを全てを列挙しきれませんね。 あんまりアニメーションの事考えられてないのかもと思いました。

という事で、これも不採用。

Google Official WebP Tools (Linux版)

Googleのサイトでダウンロード(無料)

Windows 版と同じなんでしょ?と思いましたが、こちらは連番 PNG ファイルをワイルドカード指定できます。 使えるじゃん!

という事で、めでたく採用となりました。Windows のみんなごめんな・・・。 尚、筆者は Mac を持ってないので、Mac OS 版は試してないですが、多分使えると思う。

Windows の方、ここで諦めなくても大丈夫です。 WSL2 を使って Ubuntu を入れれば 使えますし、筆者もそれで使っています。

Docker で適当な Linux のイメージを落としてきて使っても良いと思います。手間と言ってもボリュームマウントの設定が必要なくらいです。

4. img2webp の使い方

それでは、ここからは Linux 環境が準備出来たとして、変換ツールの img2webp の使い方を解説します。

その前に、肝心のアニメーションを After Effects 等で作成して、PNG 連番にレンダリングしておいてください。 今回は、1080p 60fps でアニメーションを作ったものとします。

まず、ダウンロードしてきた Linux 用の WebP Tools を解凍します。

tar zxvf libwebp-1.1.0-linux-x86-64.tar.gz

bin ディレクトリの下にバイナリが格納されてるので、適当なディレクトリにコピーして、パスを通してください。 以下、パスが通っているものとして進めます。

コマンドラインで img2webp を実行します。

img2webp -o animation.webp -loop 1 -q 75 -d 16 ./images/*.png

出来上がるまでしばらく時間が掛かります。 完了すると -o で指示した通り、カレントディレクトリに animation.webp というファイルが出来ます。

以下、コマンドラインオプションの説明です。

全てのオプションはこちらを参照してください

オプション機能
-o出力先 webp ファイルパス
-loopループ回数。1はループなし、0 は無限ループです。
-q品質係数。0 から 100 の整数で指定。デフォルトは 75。数字が大きいほど低圧縮率高品質となる。
-dフレームとフレームの間隔(ミリ秒)。16 ミリ秒なら大体 60fps。整数指定なので丸め誤差が・・・気にするな!
./images/*.png連番ファイルパス。複数指定することもできます。

出来上がった動画が下記の物です(クリックで表示)。

こちらの動画で2.5MB 程度なので、アルファ付きの 1080p 60fps 動画としてはまあまあコンパクトな方かなーと思います。 もっと圧縮率を高くしたり解像度を落としたりすることでサイズは小さくできるでしょう。

5. アニメーション WebP の使い方

次のような html コードで、WebP をページに埋め込んでください。 fallback.png は picture に非対応のブラウザで表示されるデフォルト画像です。

<picture>
    <source srcSet="/images/animation.webp" type="image/webp" />
    <img src="/images/fallback.png" alt="title" />
</picture>

必要に応じて img がオーバーレイになる様、スタイルを設定してください。

.overlay {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    pointer-events: none;
}

.overlay img {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    height: auto;
    width: auto;
    max-width: 100%;
    max-height: 100%;
    margin: auto;
    pointer-events: none;
}

Animated gif と同じで、再生は表示された瞬間から始まります。 変換時にループを設定していなければ、最後のフレームまで再生されるとそのまま停止します。

React でボタンクリックに合わせてエフェクトを再生するサンプルコンポーネントを下記に示します。 blank.png は何もない透明な画像です。 React では DOM がキャッシュされるので、再度表示したときにアニメーションが再生されない場合があります。 対策として、エフェクトが非アクティブになったら blank.png に差し替えます。

初回ロードに時間が掛かるかもしれないので、WebP ファイルはプリロードを仕込んでおいた方がいいでしょう。

import React, {useState} from 'react';

interface OverlayEffectProps {
    src: string,  // WebP ファイル
    fallback: string,  // 非対応ブラウザ用デフォルト画像
    duration: number,  // アニメーション尺(ミリ秒)
}

const OverlayEffect = (props: OverlayEffectProps) => {
    const [active, setActive] = useState(false);

    const handleClick = () => {
        setActive(true);
        setTimeout(() => {
            setActive(false);
        }, props.duration)
    }

    return <div>
        <div className="buttons is-centered">
            <button className="button is-success" onClick={handleClick} disabled={active}>エフェクト再生!</button>
        </div>
        <div className={`overlay ${active ? '': 'is-hidden'}`}>
            <picture>
                <source srcSet={active ? props.src : '/images/blank.png'} type="image/webp"/>
                <img src={active ? props.fallback : '/images/blank.png'} alt="title" />
            </picture>
        </div>
    </div>
}

export default OverlayEffect;

やっぱ、将来的には After Effects から直接 WebP に書き出したいですね。