Webpの向き不向き
WebpにはLosslessとLossyの2つのオプションがある。常識的に考えて、Losslessはファイル容量がデカくなりがちで、ファイル容量を小さくしたければLossyを使えばいいと思うが、意外とそんなことないので、用途を考えて使い分けましょうという話。

最近、ScanSnapのix1300で本をスキャンするようになった。白黒の最高解像度でスキャンをする場合、PDFで画像が出力される。PDFよりも汎用的な画像ファイルのほうが都合がいいので、pdfimagesで画像を抜き出している。
PDFから画像をTiffで抜き出す
PDFが一個だけ
$base = (Get-Item *.pdf).BaseName; pdfimages -tiff *.pdf temp; Get-ChildItem temp-*.tif | ForEach-Object { Rename-Item $_ ($_.Name -replace '^temp-',"$base-") }
複数PDF
Get-ChildItem *.pdf | ForEach-Object { $base = $_.BaseName; pdfimages -tiff $_.Name temp; Get-ChildItem temp-*.tif | ForEach-Object { Rename-Item $_ "$base-$($_.Name -replace 'temp-','')" } }
Lossy Webpに変換
そのまま出力してもあまり使いやすくないので、TIFFに出力し、それをcweb.exeでWebpに変換している。
Get-ChildItem *.tif | ForEach-Object { cwebp -q 82 -m 6 -af -mt "$_" -o "$($_.BaseName).webp"; if($LASTEXITCODE -eq 0) { Remove-Item $_ } }
深く考えずに、Lossy Webpに変換していたのだが、なんとTIFFファイルよりもファイル容量が大きくなったので、びっくり。
Lossless Webpに変換
ダメ元でLossless Webpに変換したら非常に小さなファイル容量になった。
Get-ChildItem *.tif | ForEach-Object { cwebp -lossless -z 9 "$_" -o "$($_.BaseName).webp"; if($LASTEXITCODE -eq 0) { Remove-Item $_ } }
Losslessの方が小さい?なんで?
Lossless WebPは、PNGと同様に画像の冗長性やパターンを利用して圧縮しする。つまり、単純な画像(白黒スキャン、図表、ロゴ、アイコンなど)では圧縮率が非常に高くなる。色の繰り返し、エッジの鮮明さ、パターンが多いほど効率的。
Lossy WebPは、写真のような複雑な画像向けに設計されていて、複雑なグラデーションや自然な質感を効率的に圧縮する。単純な画像だと、そのアルゴリズムが逆に非効率になることも
白黒スキャン画像は色数が少なく繰り返しパターンが多いので、Losslessが大活躍するわけ。
逆に、カラースキャンのように、輪郭に中間色が入ってくるようになると、効率はガクッと下がる。
- 文字がぼやけない
- ファイルサイズも小さい
- 圧縮率が高い
- 視覚的な劣化が少ない
じゃあ何を使えばいいのよ?
基本的にはLossy Webpを使っていればいい。白黒スキャンしたドキュメントなど、TIFFやPNGでも小さい画像はLossless Webpを検討してもいいかなという感じ。
