cwebpでWebPへフォルダ内のJPG・PNG画像を一括変換するシェルスクリプト

# プロローグ

EdgeのレンダリングエンジンもChromeと同等になり対応、またSafariも対応してきたWebP。

ひと手間増えて面倒だけど、いよいよWebPを通常採用する時期にきたのかもしれませんね...

## 参考サイト

[Big Sur搭載のSafariはWebP画像を標準サポート、AVIFもサポートしてくれるかも](https://www.suzukikenichi.com/blog/safari-on-big-sur-now-supports-webp/)
[Can I use WebP ?](https://caniuse.com/?search=WebP)

# 本稿の内容

* `cwebp`とシェルスクリプトを使って、任意のディレクトリ内のJPG画像およびPNG画像を、一括変換する方法の共有
* ※本稿はmacで動作確認をしています。他のOSは適宜調整ください。

# タスク
## （準備）cwebpのインストール
* cwebpのインストール方法はググるとたくさん出てくるので、詳細は省略
* Google公開しているインストール方法→[Getting cwebp, dwebp, and the WebP Libraries](https://developers.google.com/speed/webp/docs/precompiled)

## (1)シェルスクリプトの用意
* メモ帳（テキストエディタ）を開き、下記のスクリプトをコピペ
* ファイル名`convert2webp.sh`で保存（ファイル名は何でもいいけど）

```sh:convert2webp.sh
#!/bin/sh
Files=$(find . -type f -iname '*'.jpg -o -iname '*'.png)
# printf  "$Files\n"
for File in $Files
do
    echo $File
    cwebp -preset photo -metadata icc -sharp_yuv -o $File".webp" -progress -short $File
    printf "\n----------------\n\n"
done
```

## (２)画像のあるディレクトリへ、シェルスクリプトを配置
* 任意のディレクトリへ`convert2webp.sh`と、変換したい画像を配置します
* 画像はディレクトリ毎に分けていてもOKです
* 例えば、こんな感じ↓です

![スクリーンショット 2021-05-02 13.58.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/3298ec55-9020-9b20-1568-0069df640ea7.png)

## （3）シェルスクリプトの実行

```terminal:terminal
$ sh convert2webp.sh
```

* 変換が始まります

![スクリーンショット 2021-05-02 14.00.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/7b21d73f-c3bf-2cab-3a1f-15b78d3ece35.png)

## ビフォア・アフター
* ↓左が変換前、右が変換後
* `｛$ファイル名｝.webp` という変換後のファイルが生まれていることが確認できます

![スクリーンショット 2021-05-02 14.23.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/5ebbc913-f54c-0000-2fd7-48028b711ead.png)


# シェルスクリプトを少し解説

## #!/bin/sh
```sh:convert2webp.sh
#!/bin/sh
```
* シェルスクリプトを記述する際の、おまじない
* ちゃんと知りたいなら→[#!/bin/sh は ただのコメントじゃないよ！ Shebangだよ！](https://qiita.com/mohira/items/566ca75d704072bcb26f)

## find . -type f -iname *.jpg -o -iname *.png
```sh:convert2webp.sh
Files=$(find . -type f -iname *.jpg -o -iname *.png)
printf  "$Files\n"
```

* `find .`でカレントディレクトリ内を検索します
* オプション`-type f`で検索対象を「ファイル」に指定（なお`-type d`なら対象をディレクトリに指定）
* `-iname *.jpg -o -iname *.png`で検索対象の拡張子をフィルタリング。`-iname`は大文字、小文字を区別しないで検索（`*.jpg`も`*.JPG`も拾う）。`-o`は「OR」の意味
* `find 〜`のコマンドを`Files`へ代入
* この時点で`printf  "$Files\n"`すると、こんな感じ↓

![スクリーンショット 2021-05-02 14.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/9c368f38-c9b6-99b6-8e1b-8d48c17b8d74.png)

### (余談）変数への代入の"＝"の前後にスペースを入れるとエラーになる
```sh:convert2webp.sh
Files=$(find . -type f -iname *.jpg -o -iname *.png) # OK
Files = $(find . -type f -iname *.jpg -o -iname *.png) # NG
```
* ちょっとはまった...
* 参考サイト：[シェルで変数への代入方法(ありがちなエラー)](https://it-ojisan.tokyo/sh-var-input-error/#keni_toc_1)


## for ~ in ~;do ~ done
```sh:convert2webp.sh
for File in $Files
do
    echo $File
    cwebp -preset photo -metadata icc -sharp_yuv -o $File".webp" -progress -short $File
    printf "\n----------------\n\n"
done
```

* `for ~ in ~;do ~ done`で`$Files`をループ処理。`$File`として取り出して、一つひとつ変換。
* `echo $File`と`printf "\n---\n\n"`はターミナル上の進行状況を見やすくするために入れたので、処理自体には入れなくてもよい（不要な）部分です
* `cwebp ~オプション~ $File`でWebP変換
* `-preset photo -metadata icc -sharp_yuv -o $File".webp" -progress -short`がオプションです
* 特に`-o $File".webp"`で出力先および変換後のファイル名を指定していることに注目。この設定では、変換前のファイルと同じディレクトリへ、`｛$ファイル名｝.webp`という名称で保存されることになります
* その他のオプションについては、下記の参考サイトをご参照ください

### 参考サイト：cwebpのオプション
* [cwebp Encoder](https://developers.google.com/speed/webp/docs/cwebp)
* [【保存版】知らないと画質が落ちるWebP変換おすすめパラメーター設定例 JPEG/PNG編](https://blog.ideamans.com/2020/08/webp-params-2020.html)