WebP 対応・導入

WebP フォーマットの画像をサイトに導入する(対応する)ための覚書です。JPEG や PNG 画像を WebP 画像に変換する方法や WebP 画像の表示方法などについて。

作成日:2020年2月5日

WebP とは

WebP は Google が開発している静止画像のフォーマットでファイルの拡張子は .webp です。

以下はウィキペディアからの抜粋です。

ウェブサイトのトラフィック量軽減と表示速度短縮を目的としており、インターネットのWebページで広く使われている非可逆圧縮のJPEGや可逆圧縮のGIF、PNGの置き換えを意図する規格である。JPEGとは異なり、非可逆圧縮でもアルファチャンネルを扱える。

以下のサイトに WebP について詳しい解説などがあります。

Web サイトのアクセススピードを改善する方法の1つに画像軽量化があります。もし画像のサイズが大きい場合は、WebP のフォーマットの画像に変換することで改善できる可能性があります。

但し、現時点(2020年2月)では全てのブラウザが WebP をサポートしているわけではなく、Chrome、Firefox、Edge は対応していますが Safari、iOS は未対応です。

https://caniuse.com/#search=webp

このため、導入する場合は、対応しているブラウザでは WebP 画像を表示し、対応していないブラウザでは JPEG や PNG 等の画像を表示するようにしなければなりません(WebP 画像を表示)。

画像の最適化が必要かどうか

画像の最適化が必要かどうかは WebPageTest.orgLighthouse(Chrome 拡張機能)などで確認することができます。

全てのサイトで画像の最適化が必要なわけではありません。例えば、以下は WebPageTest.org で調べた例ですが、このサイトの場合すでに画像は十分に圧縮されているので WebP に変換する必要はありません。

ページの下の方に結果の詳細が表示されているので確認すると「potential savings = 0.0 KB」となっていてこれ以上圧縮しても意味がありません。

すでに十分に圧縮されている低画質の JPEG 画像を WebP に変換すると JPEG による歪みも保存され品質が二重に損なわれてしまうようです。

参考サイト:画像の最適化を自動化する

WebP に変換した場合のシミュレーション

WebP に変換することで、どのくらい軽くなるかをシミュレーションしてくれる以下のようなサイトがあるので利用すると便利です。

無料でページをまるごとWebP変換

シミュレーションでの結果をみて WebP を導入するかを検討するのが良いと思います。前述の例のサイトの場合、こちらのシミュレーションでもあまり効果がないことがわかります。

以下の例の場合、JPEG に関しては変換しても 1.4% しか削減できませんでした。また、画像によってはサイズが大きくなるものもありました(サイズが大きくなるケース)。

画像を WebP に変換

画像を WebP に変換するには色々な方法があるようです。

  • Google Chrome Labs が開発した Web アプリ Squoosh を利用(1枚ずつ変換)
  • 無料のクロス プラットフォーム一括画像処理変換ツール XnConvert を使用(個人での使用は無料)
  • Google Chrome Labs が開発した Photoshop のプラグイン WebPShop を使用
  • パッケージをインストールして使用 Downloading and Installing WebP
  • WordPress の場合は EWWW Image Optimizer Cloud などのプラグインを利用

画像を WebP に変換する際の注意点

以下は「画像の最適化を自動化する/画像を WebP に変換するにはどうすればいいか?」からの抜粋です。

注: 低品質または平均的な品質の JPEG を WebP に変換することは避けてください。 これはよくある間違いであり、JPEG 圧縮のアーティファクトが入る WebP 画像が生成されることになります。 その場合、画像と共に JPEG による歪みも保存しなければならないことになるため、品質が二重に損なわれてしまい、WebP の効率が低くなってしまいます。 変換アプリには、入手可能な最高品質のソース ファイル、できればオリジナルを使用してください。

Squoosh

以下は Web アプリ Squoosh を使って 850kb(高画質)の画像を変換する例です。

画像をドラッグ&ドロップすると以下のように、左側が元の画像、右側が変換後の画像が表示されます。また、右下に変換のオプションが表示されるのでフォーマットを WebP にしています。その他にもいろいろなオプションがあり細かな設定が可能です。右下のダウンロードのアイコンをクリックすると変換後の画像をダウンロードすることができます。

この例の場合、デフォルトの設定(Quality:75)で 83% 縮小できました。Photoshop を使って JPEG で圧縮する場合の画質 36(中画質)ぐらいに該当するようです。

WebP に変換するとサイズが大きくなるケース

以下はすでに Photoshop を使って 88kb に圧縮してある低画質の画像を WebP に変換する例です。

変換後の画像は 122kb と元の画像よりサイズが大きくなっています。

Homebrew で cwebp をインストール(Mac の例)

Mac の場合 Homebrew を使って簡単に WebP 変換用のパッケージ(コマンド)をインストールすることができます。

Downloading and Installing WebP | Installation instructions

以下は Homebrew がすでにインストールされていることを前提にしています。

ターミナルで brew install webp と入力して WebP 変換用コマンド をインストールします。

brew install webp    return  #webp をインストール
Updating Homebrew...
・・・中略・・・
==> Installing webp
==> Downloading https://homebrew.bintray.com/bottles/webp-1.1.0.mojave.bottle.ta
==> Downloading from https://akamai.bintray.com/81/819c76cbf75c1d1d51db88602b69a
######################################################################## 100.0%
==> Pouring webp-1.1.0.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/webp/1.1.0: 39 files, 2.1MB    # インストール完了

webp のインストールが完了すると、以下のコマンドがインストールされます。

  • cwebp -- WebP encoder tool(WebP を使って画像を圧縮)
  • dwebp -- WebP decoder tool(WebP ファイルを、PNG、PAM、PPM、PGM イメージに変換)
  • webpmux -- WebP muxing tool(アニメーション WebP の作成)

man コマンドで書式やオプションなどを確認することができます。

cwebp コマンド

WebP への変換は cwebp コマンドを使います。PNG, JPEG, TIFF などのフォーマットの画像を WebP に変換することができます(GIF の変換には gif2webp が必要です)。

以下が書式です。変換する画像ファイル(input_file)を指定し、-o オプションの後に出力する画像名(output_file 拡張子は .webp)を指定します。

cwebp [オプション] input_file -o output_file.webp

以下はカレントディレクトリの JPEG 画像(sample_01.jpg)を WebP 画像(sample_01.webp )に変換する例です。変換後のサイズは「Output」に「143700 bytes」と表示されています。

cwebp sample_01.jpg -o sample_01.webp    return #変換を実行
Saving file 'sample_01.webp'
File:      sample_01.jpg
Dimension: 1200 x 800
Output:    143700 bytes Y-U-V-All-PSNR 37.11 43.58 44.78   38.46 dB
           (1.20 bpp)
block count:  intra4:       2781  (74.16%)
              intra16:       969  (25.84%)
              skipped:        62  (1.65%)
bytes used:  header:            280  (0.2%)
             mode-partition:  14657  (10.2%)
 Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
    macroblocks:  |      29%|       8%|      15%|      48%|    3750
      quantizer:  |      36 |      30 |      24 |      17 |
   filter level:  |      11 |       6 |       4 |      20 |
   
ls -lh   return #830K が 140K に圧縮されている
-rw-r--r--@  1 xxxxx  staff   830K  2  6 06:43 sample_01.jpg
-rw-r--r--@  1 xxxxx  staff   140K  2  6 09:08 sample_01.webp 

-q オプションで1〜100の値(圧縮率)を指定することもできます。デフォルトは75です。

以下は圧縮率を 70 に指定して変換する例です。

cwebp -q 70 sample_01.jpg -o sample_01_70.webp
Saving file 'sample_01.webp'
File:      sample_01.jpg
Dimension: 1200 x 800
Output:    133652 bytes Y-U-V-All-PSNR 36.46 43.38 44.60   37.85 dB
           (1.11 bpp)
block count:  intra4:       2646  (70.56%)
              intra16:      1104  (29.44%)
              skipped:        75  (2.00%)
bytes used:  header:            259  (0.2%)
             mode-partition:  14073  (10.5%)
 Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
    macroblocks:  |      29%|       8%|      15%|      48%|    3750
      quantizer:  |      39 |      33 |      26 |      19 |
   filter level:  |      11 |       7 |      23 |      21 |
コマンドで一括変換

ターミナルでコマンドを入力して一括で変換することもできます。

for 文

以下は for 文を使ってカレントディレクトリの拡張子が jpg の画像を変換する例です。一括変換する画像のフォルダに移動してから以下のコマンドを実行します。

以下の場合、変換後の(生成される)ファイル名には、元の拡張子を残しています(.jpg.webp)。

for file in *.jpg; do cwebp $file -o ${file}.webp; done   return #変換を実行
Saving file '001.jpg.webp'   # 元のファイル名(拡張子付き)に .webp が付きます
File:      001.jpg
Dimension: 3776 x 2520
Output:    740818 bytes Y-U-V-All-PSNR 39.63 42.61 44.02   40.54 dB
           (0.62 bpp)
block count:  intra4:      28880  (77.45%)
              intra16:      8408  (22.55%)
              skipped:       296  (0.79%)
bytes used:  header:            376  (0.1%)
・・・以下省略・・・

変換後のファイル名に元の拡張子を残らないようにするには、パラメータ展開 ${変数名%パターン} を使って以下のようにします。

for file in *.png; do cwebp $file -o ${file%.*}.webp; done
Saving file 'sample_01.webp'   # 元の拡張子は取り除き .webp にする
File:      sample_01.png
Dimension: 1019 x 651
・・・以下省略・・・

以下は WebP 公式ページの FAQ に掲載されいている例です。

for F in *.jpg; do cwebp $F -o `basename ${F%.jpg}`.webp; done

以下は、引数に拡張子を受け取る簡単なシェルスクリプト webp_for の例です。拡張子を指定しない場合は .jpg が対象になります。

webp_for
#!/bin/bash
extension='.jpg'
if [ $1 != '' ]; then
  extension=."$1"
fi
for file in *"$extension"
do
  cwebp $file -o ${file}.webp
done

webp_for という名前のスクリプトを作成して、実行権限を設定します。以下はカレントディレクトリに配置したスクリプトで、カレントディレクトリにある拡張子が png の画像を WebP に変換する例です。

chmod u+x webp_for    return #実行権限を自分だけに設定
      
./webp_for png    return #引数に png を指定して実行
Saving file 'sample_01.png.webp'   # 元のファイル名(拡張子付き)に .webp が付きます
File:      sample_01.png
Dimension: 1019 x 651
Output:    38758 bytes Y-U-V-All-PSNR 42.72 42.45 43.18   42.75 dB
           (0.47 bpp)
・・・以下省略・・・

find

以下は find コマンドの -exec オプションを使ってカレントディレクトリの拡張子が jpg の画像を変換する例です。一括変換する画像のフォルダに移動してから以下のコマンドを実行します。

以下では -maxdepth オプションを指定してカレントディレクトリの画像のみを対象にしています。このオプションを指定しなければ、配下のディレクトリの画像も全て対象になります。

find ./ -maxdepth 1 -type f -name '*.jpg' -exec cwebp {} -o {}.webp \;  return
Saving file './/002.jpg.webp'
File:      .//002.jpg
Dimension: 3776 x 2520
Output:    378382 bytes Y-U-V-All-PSNR 41.40 46.20 47.93   42.60 dB
           (0.32 bpp)
・・・以下省略・・・

以下は、引数に対象のフォルダの深さを受け取る簡単なシェルスクリプト webp_find の例です。

引数に何も指定しなければ、カレントディレクトリの拡張子が .jpg または .png の画像を WebP に変換します。引数に 0 を指定すれば配下のディレクトリ全てを対象にし、0以外の数値を指定すれば指定した数の階層のディレクトリを対象にします。

以下のスクリプトの場合、拡張子が .jpeg や .JPG のファイルは変換されません。

#!/bin/bash
depth='-maxdepth '
if [ "$1" = 0 ]; then
  depth=''
elif [ "$1" = '' ]; then
  depth='-maxdepth 1'
else 
  depth='-maxdepth '$1
fi
path=`pwd`
files=`find $path ${depth} -type f -name '*.jpg' -o -name '*.png'`;
for file in $files
do 
  cwebp $file -o ${file}.webp
done

WebP 画像を表示

WebP をサポートしている Chrome などのブラウザでは img 要素を使って JPEG などの通常の画像と同じように記述すれば、WebP フォーマットの画像が表示されます。

<img src="../images/sample_01.webp" alt="WebP フォーマットの画像サンプル">

以下は上記のマークアップでの画像の表示です。現時点(2020年2月)では Chrome や Firefox では画像が表示されますが、Safari などでは表示されません。

WebP フォーマットの画像サンプル

WebP フォーマットに対応していないブラウザを考慮すると、WebP フォーマットの画像と JPEG や PNG などの従来のフォーマットの画像を用意しておく必要があります。

picture 要素を使う

picture 要素を使うとユーザーの閲覧環境(画面や端末の条件)に応じた画像を表示することができます。

picture 要素は複数の source 要素と1つの img 要素を使います。

ブラウザは、picture 要素内の source 要素の条件(srcset, media, type 属性)を順に調べて最初にマッチしたものを選択します。 適切なものがない場合やブラウザが picture 要素をサポートしていない場合には、自動的に img 要素に指定された画像が表示されます。

以下は WebP フォーマットの画像(sample_01.webp)と従来のフォーマットの画像(sample_01.jpg)を用意して、picture 要素を使って画像を表示する例です。

source 要素の type 属性に image/webp を指定しているので、WebP フォーマットに対応しているブラウザでは sample_01.webp が表示され、未対応のブラウザでは sample_01.jpg が表示されます。

<picture> 
  <!-- WebP フォーマットの画像 type 属性に image/webp を指定-->
  <source srcset="../images/sample_01.webp" type="image/webp">
  <!-- 従来のフォーマットの画像 --> 
  <img src="../images/sample_01.jpg" alt=""> 
</picture>

※ 但し、IE11 は picture 要素に対応していません。

.htaccess を使う

.htaccess ファイルを使うと、JPEG や PNG 画像に対応する WebP フォーマット(.webp)の画像がサーバー(Apache)上に存在する場合には対応しているブラウザに WebP ファイルを配信することができます。

この方法を使えば、WebP フォーマット(.webp)の画像を用意するだけで、HTML の記述を変更する必要がありません。

拡張子の付け方

JPEG や PNG 画像に対応する WebP フォーマット(.webp)の画像を用意する場合、元の拡張子を残さないファイル名にする方法と元の拡張子を含める方法があります。

例えば、sample.jpg に対応する WebP 画像のファイル名を sample.webp とするか sample.jpg.webp とするかのどちらかになると思います。

既存の Web サイトを WebP 対応にする場合、ファイル名の競合を考慮すると元の拡張子を含めたほうが無難な気がします(元の拡張子を残さない場合、sample.jpg と sample.png があると sample.webp と同じファイル名になってしまうため)。

また、拡張子の付け方(ファイル名)により .htaccess が少し異なります。

元の拡張子を残さない場合の例

以下は、用意する WebP 画像のファイル名に元の拡張子を残さない場合の例で、sample.jpg とそれに対応する sample.webp という画像がある場合に使えるものです。

<ifModule mod_rewrite.c>
  RewriteEngine On 
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_URI}  (?i)(.*)(\.jpe?g|\.png)$ 
  RewriteCond %{DOCUMENT_ROOT}%1.webp -f
  RewriteRule (?i)(.*)(\.jpe?g|\.png)$ %1\.webp [L,T=image/webp,R] 
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

<IfModule mod_mime.c>
  AddType image/webp .webp
</IfModule>

元の拡張子を含める場合の例

以下は、用意する WebP 画像のファイル名に元の拡張子を残す場合の例で、sample.jpg とそれに対応する sample.jpg.webp という画像がある場合に使えるものです。

前述の例との違いは5行目と6行目で %2 を使って元の拡張子 (\.jpe?g|\.png) を追加している部分のみです。

<ifModule mod_rewrite.c>
  RewriteEngine On 
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_URI}  (?i)(.*)(\.jpe?g|\.png)$ 
  RewriteCond %{DOCUMENT_ROOT}%1%2.webp -f
  RewriteRule (?i)(.*)(\.jpe?g|\.png)$ %1$2\.webp [L,T=image/webp,R] 
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

<IfModule mod_mime.c>
  AddType image/webp .webp
</IfModule>

記述されている内容については .htaccess の使い方・設定方法/WebP フォーマットの画像の出し分け を参照ください。

WebP 画像が表示されているかの確認

WebP 画像が表示されているかはブラウザのインスペクタのネットワークタブで確認することができます。