LoginSignup
4
1

More than 1 year has passed since last update.

Webp画像の真髄に迫る!!

Last updated at Posted at 2022-12-05

皆様こんにちは、玉ちゃんです!!!!

いきなりですが皆様、画像の拡張子といえば何を思いつくでしょうか、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のデメリットは、、、?

非対応のブラウザが存在する

スクリーンショット 2022-12-05 11.14.19.png

上記の赤部分が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サイトに関しては対応をお勧めします!!

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1