Laravel 13.20 で追加された標準画像処理を試す

Laravel13.20で、画像処理機能がフレームワーク標準機能として追加された。

Image Manipulation | Laravel 13.x
[13.x] Adds first-party support for image processing

ちなみに、このブログシステムは初回コミットは7/11でLaravelバージョンは13.19。
13.20のリリースは7/14だった。惜しい。

このブログでは画像ファイルをアップロードするときに、画像サイズ最適化など簡単な処理をやっている。

現在の処理

use Illuminate\Http\UploadedFile;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;

class ImageOptimizer
{
    private const MAX_WIDTH = 1600;
    private const QUALITY = 82;

    public function optimize(UploadedFile $file, string $destPath): void
    {
        if ($file->getMimeType() === 'image/gif') {
            $file->move(dirname($destPath), basename($destPath));

            return;
        }

        $image = (new ImageManager(new Driver))->decodePath($file->getPathname());

        if (extension_loaded('exif')) {
            $image->orient();
        }

        $image->scaleDown(width: self::MAX_WIDTH);
        $image->save($destPath, quality: self::QUALITY);
    }
}

現状は、ImageManagerクラスを使って画像処理を行っている。
画像処理ライブラリとしてはIntervention Imageが使われる。

13.20で追加されたImageファサードも、内部的にはIntervention Imageを使う。

せっかくなのでImageファサードを使った版も書いてみて比較してみたい。
まあ、機能的な差はないだろうし、元コードもシンプルなのであまり変化はなさそうだが。

ざっと書き直してみた。

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Image;

class ImageOptimizer
{
    private const MAX_WIDTH = 1600;
    private const QUALITY = 82;

    public function optimize(UploadedFile $file, string $destPath): void
    {
        if ($file->getMimeType() === 'image/gif') {
            $file->move(dirname($destPath), basename($destPath));
						
            return;
        }

        $image = Image::fromUpload($file)
            ->when(extension_loaded('exif'), fn ($image) => $image->orient())
            ->scale(width: self::MAX_WIDTH)
            ->quality(self::QUALITY);

        File::put($destPath, $image->toBytes());
    }
}

行数的にはほぼ変わらない。
メイン処理がメソッドチェーンでひとまとまりになりシンプルになった気はする。

ドライバの指定が設定ファイル依存になったので、そこは綺麗な構造になったと言えるか?

あとは、Imageファサード経由で使うようになったので、Intervention Image側で何か変更があったとしてもフレームワークが吸収してくれるのがメリットか。

今回の例では、わざわざ書き直すメリットはあまりないかもしれないけど、メソッドチェーンで書けるのはシンプルでいい気がするので、今後は使っていく価値がありそう。

ちなみに、画像の保存にはstore()関数があるので通常はそれを使えばいい。
このブログでは静的配信をする都合で指定ディレクトリに置きたいのでFile::put()を使っている。

Laravel Image Responses: Serve Resized Images From Routes

13.25でさらに機能が増えたらしい。