【WebP(ウェッピー)変換】JPEGやPNG画像の色味を変えずにWebP画像へ一括変換


## なに？
デザイナーさんに画像をWebPに変換して貰ったところ、「なんか色味が違うぞ？」となり、調べた際のメモ。

## WebPとは？
- WebP（ウェッピー）
- 画像フォーマット
- 圧縮率が高い
- 非可逆圧縮
- 拡張子「.webp」
- Googleが開発
- 発表は2010年
- 2020年からiOS14でも対応
- libwebpライブラリを使ってエンコード・デコード

## 「libwebp」とは

Googleが提供しているWebP向けのライブラリです。
このライブラリを使うとWebPエンコード、デコードがコマンドから実行出来ます。
巷のWebP変換ツール系アプリもこのコマンドをラップしたものが多い様です。

### セットアップ

まずはここから環境にあった本体をダウンロード。

https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html

今回私は、`libwebp-1.3.0-mac-x86-64.tar.gz` をダウンロードしました。

これを展開して適当な場所に配置し、パスを通しておきます。

~/.zshrc など

```text
# libwebp
export PATH="$HOME/libwebp/libwebp-1.3.0-rc1-mac-x86-64/bin:$PATH"
```

```bash
source ~/.zshrc
```

動くかどうか、ヘルプで確認
```bash
cwebp -h
```

結果
```bash
Usage:

   cwebp [options] -q quality input.png -o output.webp

where quality is between 0 (poor) to 100 (very good).
Typical value is around 80.

Try -longhelp for an exhaustive list of advanced options.
```
動きました。

### WebP変換

まずはJPG画像をWebPに変換してみます。

オプション
- Quality: 50％
- インプット: input.jpg
- アウトプット: output.webp

```bash
cwebp -q 75 -o output.webp input.jpg
```

## 本題「色味が落ちる」

cwebpコマンドはそのまま実行すると、圧縮時に **「ICCプロファイル」** という色情報が削除されてしまいます。
ほとんどの場合は気にならないと思いますが、サイトの目立つ画像だったりすると少し色褪せたように感じるケースがありました。

そこで、cwebpコマンドのICCプロファイルを残したまま圧縮するオプションを試してみたいと思います。

- `-metadata icc`

```bash
cwebp -q 50 -metadata icc -o output_with_icc.webp input.jpg
```

さらに、以下のオプションを追加すると

- `-sharp_yuv`

境界の色味をできる限り補正してくれます。

デメリットは
- ファイルサイズが若干増える
- CPUやメモリの負荷がかかる

ローカルでのちょっとした作業程度であれば、問題にはならなそうですね。


```bash
cwebp -q 50 -metadata icc -sharp_yuv -o output_with_icc.webp input.jpg
```

## 検証してみる

### オリジナル画像
- **606 KB**
![bon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681323/e3934276-638b-98e0-e10d-0d4c08fdef26.jpeg)

### WebP変換後
- **172 KB**

（QiitaにWebPがアップロードできないのでキャプチャ。。。）
![スクリーンショット 2023-02-21 16.15.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681323/ef8f84ff-1489-ea3f-7013-d3f600c29776.png)

実物を見比べてもほぼ遜色なし。いい感じです。
しかも **606KB→172KB** とサイズもかなり圧縮されています。

## おわりに

こちらは、指定したディレクトリにある画像をWebPに変換する簡単なスクリプトです。
指定したディレクトリ以下に`WebP/`ディレクトリを作成して、そこに変換したWebP画像を書き出します。

```bash
#!/bin/bash

input=$1
quality=${2:-50}

if [ $# = 0 ]; then
    echo 'ファイルまたはディレクトリが指定されていません'
    exit 1
elif ! [[ $quality =~ ^[0-9]+$ ]]; then
    echo '圧縮率は整数で入力して下さい'
    exit 1
else
    echo "Input File: ${input}"
    echo "Quality: ${quality}"
fi

files=()
outputDir=''
if [ -d $input ]; then
    # Dir
    files=($(find $input -type f \( -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" \)))
    input=${input%/}
    outputDir=$input/webp
elif [ -f $input ]; then
    # File
    files=($input)
    outputDir=$(dirname ${input})/webp
else
  echo "$input はディレクトリでもファイルでもありません。"
  exit 1
fi

# Convert to WebP
mkdir $outputDir
for inputfile in ${files[@]}; do
    inputDir=$(dirname ${inputfile})
    inputDir=${inputDir%/}
    inputFilePath=$inputDir/$(basename ${inputfile})
    echo "Input File Path: $inputFilePath"
    outname=$(basename ${inputfile}|sed 's/\.[^\.]*$//')
    output=$outputDir/$outname.webp
    echo "WebP Output Directory: $output"
    cwebp -q $quality -metadata icc -sharp_yuv -o $output $inputFilePath
done

echo "✅ WebP Converting Process Did Complete"

# Open Output Dir
open $outputDir

```

使い方
```bash
./sample_convert.sh ./target-images 50
```

これからは許される限りどんどんWebPを使っていこうと思います🙌



## 参考

https://developers.google.com/speed/webp/docs/using?hl=ja

https://blog.ideamans.com/2020/08/webp-params-2020.html