画像をWebPにすると軽くなると言われるが、どれだけ小さくなるかは設定と画像の中身で変わる。
変換の方式には、元の画素をそのまま保つものと、情報を捨てて小さくするものがある。
ここでは、実際に手元で変換して測った数値をもとに、どちらを選ぶかの考え方を整理する。
測定は2026年9月20日にPython 3.13とPillow 12.3.0で実行した。
実際に測った数値
同じ画像をPNGとWebPで保存し、大きさと、元の画素との差を比べた。
1枚目は文字と単色の面が多い画像(1280×720)である。
| 保存の仕方 | 大きさ | PNG比 | 元と一致 | 画素の平均差 | 最大差 |
|---|---|---|---|---|---|
| PNG | 82,785 バイト | 100% | — | — | — |
| WebP 可逆 | 45,614 バイト | 55.1% | 一致する | 0 | 0 |
| WebP 品質90 | 14,908 バイト | 18.0% | 一致しない | 1.08 | 19 |
| WebP 品質80 | 10,986 バイト | 13.3% | 一致しない | 1.14 | 35 |
| WebP 品質75 | 9,700 バイト | 11.7% | 一致しない | 1.17 | 38 |
2枚目は別の図版(1280×720)で、傾向は同じだった。
| 保存の仕方 | 大きさ | PNG比 | 画素の平均差 | 最大差 |
|---|---|---|---|---|
| PNG | 91,319 バイト | 100% | — | — |
| WebP 可逆 | 51,652 バイト | 56.6% | 0 | 0 |
| WebP 品質90 | 15,454 バイト | 16.9% | 0.99 | 16 |
| WebP 品質80 | 11,356 バイト | 12.4% | 1.07 | 23 |
| WebP 品質75 | 9,966 バイト | 10.9% | 1.10 | 31 |
平均差と最大差は、0から255までの値としての差である。
平均が1前後でも最大が30を超える箇所があり、差は画像全体に均等ではない。
2つの方式の違い
| 方式 | 画素 | 小ささ | 向いている画像 |
|---|---|---|---|
| 可逆 | 元と完全に同じ | PNGの約55% | 図版、スクリーンショット、透過が要るもの |
| 非可逆 | わずかに変わる | PNGの1〜2割 | 写真、細かい階調が多いもの |
可逆でもPNGから半分近くまで落ちるため、画素を変えたくない場合でも置き換える価値がある。
一方で、非可逆にすると1割台まで落ちるので、差が大きい。
この差をどう受け取るかは、その画像が何に使われるかで変わる。
どちらを選ぶかの決め方
画像の中身より先に、その画像に求める性質を決めるほうが早い。
| 求める性質 | 選ぶ方式 | 理由 |
|---|---|---|
| 文字がにじんでは困る | 可逆 | 非可逆は輪郭の周りに差が出る |
| 色を正確に伝えたい | 可逆 | 画素が変わらない |
| 読み込みを軽くしたい | 非可逆 | 1割台まで落ちる |
| 元画像として保管する | 可逆またはPNGのまま | あとから作り直せる |
| 透過が要る | どちらも可 | WebPは透過に対応している |
スクリーンショットや図版で文字が入っているものは、非可逆にすると輪郭の周りに差が出やすい。
実測でも、文字と単色の面が多い画像のほうが最大差が大きかった。
オンラインの変換を使うときに見るところ
ブラウザーで変換できるサービスは多いが、確かめておきたい点がいくつかある。
- 可逆と非可逆を選べるか(選べないものは非可逆のことが多い)
- 品質の数値を指定できるか
- 元のファイルがどこへ送られるか(手元で処理するものと、送信するものがある)
- 変換後にサイズを確かめられるか
- 透過が残るか
公開前の資料や、他人から預かった画像を扱う場合は、送信の有無を先に確かめる。
手元で処理する形のサービスであれば、ファイルは外に出ない。
手元で変換する
同じ設定で何枚も変換するなら、手元で処理するほうが早い。
PythonのPillowを使う場合はこう書ける。
from pathlib import Path
from PIL import Image
for src in Path("対象のフォルダー").glob("*.png"):
im = Image.open(src)
# 画素を変えない
im.save(src.with_suffix(".webp"), "WEBP", lossless=True)
# 小さくしたい場合
# im.save(src.with_suffix(".webp"), "WEBP", quality=80)変換したあと、元と一致しているかを確かめたい場合は次のようにする。
from PIL import Image, ImageChops, ImageStat
a = Image.open("元.png").convert("RGB")
b = Image.open("変換後.webp").convert("RGB")
d = ImageChops.difference(a, b)
print("一致:", d.getbbox() is None)
print("平均差:", [round(x, 2) for x in ImageStat.Stat(d).mean])ここでRGBAに変換して比べると、不透明な画像どうしでは差が出ないことがある。
実際にこの書き方で測ったときは、非可逆で圧縮したものまで一致と出てしまった。
比べるときはRGBにそろえる。
置き換えるときに気をつけること
- 元のPNGを消す前に、変換後の見た目を実際に開いて確かめる
- 差し替えるならURLも変わるため、参照している場所をすべて直す
- 印刷や再編集に使う元データは、PNGのまま残しておく
- 同じ設定で全部を変換せず、文字の多い画像だけ可逆にするなど分ける
容量を削ることだけを目的にすると、あとから作り直せない画像を非可逆にしてしまう。
まとめ
- 実測では、可逆でPNGの約55%、品質80で約13%まで落ちた
- 可逆は画素が元と完全に一致し、非可逆は平均1前後、最大30以上の差が出た
- 文字や図版は可逆、写真は非可逆という分け方が扱いやすい
- オンラインの変換は、ファイルが送信されるかどうかを先に確かめる
- 比べるときはRGBにそろえる。RGBAだと差が出ないことがある
測定は2026年9月20日にPython 3.13とPillow 12.3.0で実行したものである。
画像の中身によって数値は変わるため、自分が扱う画像で測り直してほしい。
WebPの仕様はGoogleの技術資料にまとまっている。
作業を楽にする道具はPCメソッドのまとめにも置いている。
