皆様こんにちは、玉ちゃんです!!!!
いきなりですが皆様、画像の拡張子といえば何を思いつくでしょうか、pngやjpgなどでしょうかね?
いいえ、時代はwebpです。ウェッピーと読みます。
本日は、まだまだ馴染みないであろうWebpの真髄に迫っていこうと思います。
Webpについて
webp(ウェッピー)とは、Googleが開発した次世代画像フォーマットのことであり、2010年に公式発表されました。webpは画像の圧縮率が高く、表示速度の高速化に有利に働きます。
Google先生が開発いたしました。たまーにwebサイトから画像を保存したりするとwebp拡張子のことあります。(テンション上がります)
ズバリwebp画像を利用するメリット
1:画像サイズの軽量化
画質もpngやjpgに劣らない上に、可逆圧縮にも非可逆圧縮にも対応しています!そしてとにかく軽い、軽すぎるのです!!
Webpとjpegを比較した場合約25%程度は軽量化することが可能と言われています。
2:ページスピードの改善
画像サイズが軽量化されるということは、Webサイトのページスピードに直結するのです!既に使わん理由なし!!
3:SEO面での恩恵
Googleが公表するThe Page Experience Updateという検索アルゴリズムからすると、ページスピードといった、ユーザーに対する良質なエクスペリエンスはSEOの観点からもかなり重要視されています。
(昨今のSEOではGoogle Core Web Vitalsと呼ばれるWebサイトの応答性、表示速度、デザイン性などの総評から検索エンジンの順位を決定している。)
Webpのデメリットは、、、?
非対応のブラウザが存在する
上記の赤部分が22/12時点のwebp対応ブラウザとなっています。
SafariもmacOS 11 Big Sur以前では未対応ですが、市場に多く流通しているiPhoneはすべて対応済みと考えられます、、、
しかし!!上の画像の赤枠でWebサイトを閲覧している方々も存在しないわけではありません。というか、一定数確実にいます。
Webp対応していないブラウザでは、Webp画像を表示することはできない、、
わけではなく、未対応ブラウザに対してはpngもしくはjpg画像を表示してあげれば良いのです!そう!シンプルなのです!!
ということで、実際にブラウザごとの振り分けを行いましょう!!
Webp対応ブラウザと未対応ブラウザ表示振り分け
今回は一番シンプルな、HTMLのタグを用いた対応策を紹介できればと思います。
<picture>
<source srcset=”sample.webp” type=”image/webp”>
<img src=”sample.jpg“>
</picture>
picture
タグは1つ以上のsource
タグと、1つ以上のimg
タグを子要素に含む必要があります。
ブラウザは、を上から順番に検討し、条件に該当した画像を表示してすることとなります。
そのため、Webpに対応しているブラウザの場合は、sample.webpを表示し、
未対応ブラウザの場合にはsample.jpgを表示してくれるということになります。うん、賢い(^^)v
※(しかし、IEはそもそもpicture
タグに対応していないそうなのでこちらをご参考に、、)
※(他にも、CSS側での切り分けのための「Modernizr」などのプラグインなども存在しています。)
ちょっと待てい!!!
上記のように、シンプルに表示の切り分けを行うことができるのですがpicture
タグを利用するにはwebp拡張子の画像と、png/jpg画像の2つを用意しなくてはなりません。
これ、わざわざ、面倒じゃないですか?????
では、どうするか??
※今回はS3に画像を保存していること、DBに画像pathを保持していること(webp_pathカラムとそれ以外のpathカラム[image_path]の2つが存在している)、PHP7系以上を使用していることが前提です。
簡潔ですが、利用するべき関数などを紹介できればと思います。
1:S3に元々保存されているpng/jpg画像から、webp画像を作成する。
上記の逆のパターン(S3に保存されているwebp画像からpng/jpg画像を作成する)も対応する必要もありますね。今回は、単発のバッチ処理想定で行います。
※gifの変換は行いません。
※webp画像はpng画像に複製しています
$list = "DB内の画像path達"
foreach($list as $path) {
$path = "DBに保存されているpng/jpg/webpのパス";
$path_info = pathinfo($path);
// url化
$image_url = config('config.works_image_url');
$url = $image_url . $path;
// 拡張子情報取得
$extension = $path_info['extension'];
$mime_type = null;
switch($extension) {
case 'jpg';
$image = imagecreatefromjpeg($url);
$mime_type = 'webp';
break;
case 'png';
$image = imagecreatefrompng($url);
$mime_type = 'webp';
break;
case 'webp';
$image = imagecreatefromwebp($url);
$mime_type = 'png';
break;
}
ちょこっと解説
・pathinfo()を用いて、pathの情報を分解して取得しています。拡張子の情報もこれで一発で取得できます。
・imagecreatefrom〇〇系の関数は画像作成関数でして、pathをもとにGdimage オブジェクトを返します。ここで一度画像を作成しています。
・$mime_typeに対して、後程変換するべき拡張子の情報を持たせています。
下記もforeachの中で行ってください。
if (!is_null($mime_type)) {
//複製fileNameを作成
$fileName = $path_info['filename'] . '.'.$mime_type;
// 仮保存tempフォルダ作成
mkdir(base_path('仮保存用のフォルダまでのpath'));
// 仮保存フォルダに画像パスを追加
$tmp = base_path('仮保存用のフォルダまでのpath'.$fileName);
$store_path = $path_info['dirname'];
$baseName = $store_path . '/' . $path_info['filename'];
$copy_path = $baseName . '.' . $mime_type;
// Palette imageに対応
imagepalettetotruecolor($image);
// テーブル選択
$Table = "保存先のテーブル";
if ($mime_type == 'webp') {
// webp画像作成
imagewebp($image,$tmp);
// webp_pathカラムに追加
$Table->webp_path = $copy_path;
$Table->save();
} elseif ($mime_type == 'png') {
// png画像作成
imagepng($image,$tmp);
// Webpパスをwebp_pathカラムに移動
$webp_path = $Table->image_path;
$Table->webp_path = $webp_path;
// pngパスで上書き
$Table->image_path = $copy_path;
$Table->save();
}
// S3に保存
$file = new File($tmp);
$s3_path = Storage::disk('s3')->putFileAs($store_path, $file, $fileName,'public');
if (file_exists($tmp)) {
// 画像削除
unlink($tmp);
//tempフォルダも削除
rmdir(base_path('仮保存用のフォルダまでのpath'));
}
}
ちょこっと解説
・imagewebp()やimagepng()は第一引数に、Gdimageオブジェクト、第二引数に実体を保存するpathをあげることによって画像をファイルに出力してくれる関数です。
・S3に保存するためには、画像のpathのみではなく画像の実態が必要なので仮保存しています。
・最後にunlink()とrmdir()で仮保存していたフォルダごと削除します。(S3に保存できれば必要ないので)
2:S3保存時にWebp画像を自動で作成しS3に保存する。
ここは、上記で行った処理とほぼ同じですので割愛させてください。(長くなりすぎちゃう、、)
3:最後に表示処理では上記の、タグを用いた表示を行ってください。
フロント側で、webpとpngもしくはjpgのS3のpathを渡してください。
<picture>
<source srcset=”S3内のwebp画像path” type=”image/webp”>
<img src=”S3内のpng/jpg画像path“>
</picture>
ブラウザで確認するとwebp画像が表示されるようになったと思います。
最後に
かなり長くなりましたが、表示処理の切り分けは至ってシンプルです。
Webpの恩恵を受けるためにも、特に画像を多く利用するwebサイトに関しては対応をお勧めします!!