PHP | フォルダ内にある画像ファイルをまとめてwebpに変換するサンプル

Code:

/**
 * 対象フォルダ内にある 画像を取得
 * 今回は jpg jpeg gif png
 */
$images = glob('C:/test/{*.jpg,*.jpeg,*.gif,*.png}', GLOB_BRACE);
foreach ($images as $i => $img) {
    $info = pathinfo($img);

    /**
     * 拡張子別に画像取得
     */
    $ext = $info['extension'];
    if ($ext === 'jpg' || $ext === 'jpeg') {
        $image = imagecreatefromjpeg($img);

    } else
    if ($ext === 'gif') {
        /**
         * GIFアニメ対策
         */
        $tmp = imagecreatefromgif($img);

        [$w, $h] = getimagesize($img);
        $image = imagecreatetruecolor($w, $h);
        imagecopyresampled($image, $tmp, 0, 0, 0, 0, $w, $h, $w, $h);

    } else
    if ($ext === 'png') {
        $image = imagecreatefrompng($img);

    } else {
        continue;
    }

    /**
     * 変換後 ファイルパス
     */
    $path = str_replace($ext, 'webp', $img);
    /**
     * webpに変換
     */
    $bool = imagewebp($image, $path);
    /**
     * 後始末
     */
    imagedestroy($tmp);

    /**
     * 必要であれば
     * 元の画像の削除
     */
    // unlink($image);
}
フォルダ内にある画像をまとめてwebpファイルに変換する方法を紹介していきます。
webpに変換することで、ファイル容量の圧縮、それに伴って、ページの表示速度の高速化、などなど、様々なメリットがあります。
今回のサンプルでは、jpgjpeggifpngを取得し、webpへと変換します。

    もくじ

  1. 使い方
  2. プログラムの説明
  3. 処理サンプル
  4. まとめ

使い方

変換したいファイルのあるフォルダを指定

Code:

$images = glob('C:/test/{*.jpg,*.jpeg,*.gif,*.png}', GLOB_BRACE);
変換したいファイルのあるフォルダをglob関数で指定します。
今回はjpgjpeggifpngを変換するので、正規表現で指定しています。
サンプルは「C:/test/」の中にある「jpgjpeggifpng」を一覧として取得しています。

実行

コードを記載したPHPファイルをサーバーで実行します。
ファイルが変換されたら成功となります。
※ ファイル数によってはとても時間がかかってしまうので、下記コードを記述してタイムアウトにならないようにしましょう。
set_time_limit(0);

プログラムの説明

フォルダからファイル一覧を取得

Code:

$images = glob('C:/test/{*.jpg,*.jpeg,*.gif,*.png}', GLOB_BRACE);
glob関数を利用して、パターンにマッチしたファイルを配列として取得します。
GLOB_BRACEは、複数のパターンマッチングを行うためのフラグになります。

GLOB_MARK ディレクトリに階層の区切り文字を追加します。
GLOB_NOSORT このフラグを使わない場合、パス名順ソートされます。
GLOB_NOCHECK 検索パターンにマッチするファイルが見つからない場合、 検索パターンが返ります。
GLOB_NOESCAPE バックスラッシュによるメタ文字のクォートを行いません。
GLOB_BRACE 複数のパターンにマッチさせたい場合に指定します。
GLOB_ONLYDIR パターンにマッチするフォルダのみが返されます。
GLOB_ERR 読み込みエラー時に停止します。指定しない場合、エラーは無視されます。

画像を取得

Code:

/**
 * 拡張子別に画像取得
 */
$ext = $info['extension'];
if ($ext === 'jpg' || $ext === 'jpeg') {
    $image = imagecreatefromjpeg($img);

} else
if ($ext === 'gif') {
    /**
     * GIFアニメ対策
     */
    $tmp = imagecreatefromgif($img);

    [$w, $h] = getimagesize($img);
    $image = imagecreatetruecolor($w, $h);
    imagecopyresampled($image, $tmp, 0, 0, 0, 0, $w, $h, $w, $h);

} else
if ($ext === 'png') {
    $image = imagecreatefrompng($img);

} else {
    continue;
}
ファイルの種類別に呼び出す関数が変わります。
gifの場合、エラーとなってしまうため、getimagesizeで同サイズの画像を作成し、元のgifをコピーする処理を行います。
※ アニメーションを変換しても静止画になってしまいます。

webpに変換

Code:

/**
 * 変換後 ファイルパス
 */
$path = str_replace($ext, 'webp', $img);
/**
 * webpに変換
 */
$bool = imagewebp($image, $path);
/**
 * 後始末
 */
imagedestroy($tmp);
拡張子だけを変換し、同名ファイルとして保存します。
imagewebpは、成功した場合にtrueを、失敗した場合にfalseを返します。
変換が完了したら、imagedestroyでメモリを開放します。

元画像の削除

Code:

/**
 * 必要であれば
 * 元の画像の削除
 */
// unlink($image);
サンプルではコメントアウトしていますが、必要のなくなったファイルを削除することも可能です。

処理サンプル

webpをjpg、gif、pngに変換

Code:

/**
 * webp画像取得
 */
$tmp = imagecreatefromwebp($img);

/**
 * png変換する場合
 */
$path = str_replace('.webp', '.gif', $webp);
$png = imagepng($tmp, $path);

/**
 * gifに変換する場合
 */
$path = str_replace('.webp', '.gif', $webp);
$gif = imagegif($tmp, $path);

/**
 * jpgに変換する場合
 */
$path = str_replace('.webp', '.jpg', $webp);
$jpg = imagejpeg($tmp, $path);
webpに変換できるので、もちろん戻すことも可能です。
画像を取得、変換する際の関数がそれぞれ違います。
基本的に、関数名の末尾に、取得または変換したいファイルの拡張子が名前として付きます。

再帰処理で子フォルダ内のファイルも変換

Code:

/**
 * 再帰関数
 */
function getFiles($dir, $lists) {
    /**
     * 全て取得
     */
    $ary = glob(rtrim($dir, '/') . '/*');
    foreach ($ary as $target) {
        /**
         * ファイルだったら
         */
        if (is_file($target)) {
            /**
             * 対象となるファイルだけ配列に格納
             */
            $info = pathinfo($target);
            if (in_array($info['extension'], ['jpg', 'jpeg', 'gif', 'png'], true)) {
                $lists[] = $target;
            }
        }
        /**
         * フォルダだったら
         */
        if (is_dir($target)) {
            /**
             * 子階層を確認
             */
            $lists = array_merge($lists, getFiles($target, $lists));
        }
    }
    return $lists;
}
$lists = getFiles('C:/test/', []);

foreach ($lists as $i => $img) {
    $info = pathinfo($img);

    /**
     * 
     * 上記サンプルの変換処理
     * 
     */
}

フォルダの中にフォルダがある場合、最初のサンプルでは取得できないので、再帰処理を行いフォルダ内も取得します。
globでフォルダも取得したいので、正規表現による画像の抽出が行えません。ので、取得したファイルの拡張子で判別しています。
取得した全ファイルがlistsに格納されるので、listsに対して、サンプル処理を行います。

まとめ

今回は画像ファイルの変換について紹介しました。
Google PageSpeed Insightsでも、次世代フォーマットにしなさいと言われてしまうので、今後、次世代のフォーマットが主流になっていくことでしょう。
時代に取り残されないためにも、是非サンプルを使って変換してみてください!
WebP(ウェッピー)」 知ってはいるけど、未だに 「web + p」 で、 「ウェブピー」 と呼んでいます。