> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 画像加工

> Laravel の Image ファサードを使って画像のリサイズ・クロップ・変換・保存を行う方法を解説します。

## はじめに

Laravel は `Image` ファサードを通じて、流暢な画像加工 API を提供します。リサイズ・クロップ・エンコード・保存などの操作をフレームワーク全体で一貫した表現方法で記述できます。

内部的には [Intervention Image](https://image.intervention.io/) を利用しており、PHP の GD 拡張と Imagick 拡張の両方をサポートしています。

```php theme={null}
use Illuminate\Support\Facades\Image;

$path = Image::fromStorage('avatars/photo.jpg', 'public')
    ->cover(400, 400)
    ->toWebp()
    ->quality(80)
    ->storePublicly('avatars', 'public');
```

<Warning>
  画像処理は CPU とメモリを大量に消費する可能性があります。大規模な画像処理は HTTP リクエスト中に行わず、[キュージョブ](/jp/queues) として処理することを検討してください。
</Warning>

<Info>
  この機能は **Laravel v13.20.0 以上** で利用できます。古いバージョンを使用している場合は `composer update` でフレームワークを最新版に更新してください。
</Info>

## インストール

画像加工機能を使用する前に、Composer で Intervention Image パッケージをインストールします。

```shell theme={null}
composer require intervention/image:^4.0
```

また、使用するドライバーに応じて PHP の GD 拡張または Imagick 拡張がインストールされていることを確認してください。

### 設定

設定ファイルは `config/image.php` に配置されます。設定ファイルが存在しない場合は Artisan コマンドで公開します。

```shell theme={null}
php artisan config:publish image
```

デフォルトのドライバーは設定ファイルまたは環境変数 `IMAGE_DRIVER` で指定できます。サポートされているドライバーは `gd` と `imagick` です。

```ini theme={null}
IMAGE_DRIVER=imagick
```

## 画像の読み込み

`Image` ファサードはさまざまなソースから画像インスタンスを生成するメソッドを提供します。画像の内容は遅延読み込みされるため、処理またはバイト列の要求があるまで実際には読み込まれません。

### アップロードファイル

リクエストからアップロードされた画像を取得するには `image` メソッドを使います。ファイルが存在しない場合は `null` を返します。

```php theme={null}
use Illuminate\Http\Request;

Route::post('/avatar', function (Request $request) {
    $request->validate(['avatar' => ['required', 'image']]);

    $path = $request->image('avatar')
        ->cover(400, 400)
        ->toWebp()
        ->storePublicly('avatars', 'public');

    // ...
});
```

`UploadedFile` インスタンスから生成する場合は `fromUpload` メソッドを使います。

```php theme={null}
use Illuminate\Support\Facades\Image;

$image = Image::fromUpload($request->file('avatar'));
```

アップロードファイルから生成した画像インスタンスは `file` メソッドで元のファイルを取得できます。

```php theme={null}
$file = $image->file();
```

### ストレージファイル

[ファイルシステムディスク](/jp/filesystem) に保存されているファイルから画像インスタンスを生成するには `fromStorage` メソッドを使います。第一引数はファイルパス、第二引数はディスク名です。

```php theme={null}
use Illuminate\Support\Facades\Image;

$image = Image::fromStorage('avatars/photo.jpg', disk: 'public');
```

Storage ファサードの `image` メソッドからも生成できます。

```php theme={null}
use Illuminate\Support\Facades\Storage;

$image = Storage::disk('public')->image('avatars/photo.jpg');
```

### その他のソース

バイト列・ローカルパス・URL・Base64 からも画像インスタンスを生成できます。

```php theme={null}
use Illuminate\Support\Facades\Image;

$image = Image::fromBytes($contents);
$image = Image::fromBase64($base64);
$image = Image::fromPath(storage_path('app/avatars/photo.jpg'));
$image = Image::fromUrl('https://example.com/photo.jpg');
```

## 画像の加工

画像インスタンスはイミュータブルです。各メソッドは変換を処理パイプラインに追加した新しいインスタンスを返すため、メソッドチェーンで記述できます。変換はパイプラインに追加した順に処理され、エンコードは最後に一度だけ行われます。

```php theme={null}
$image = $request->image('avatar')
    ->orient()
    ->cover(400, 400)
    ->sharpen(10);
```

### リサイズ

| メソッド                | 説明                                    |
| ------------------- | ------------------------------------- |
| `resize(800, 600)`  | 指定サイズにリサイズ。幅または高さのみも指定可               |
| `scale(800, 600)`   | 比率を保ちながら指定サイズ内に収まるよう縮小。拡大はしない         |
| `cover(400, 400)`   | 指定サイズを完全に覆うようリサイズ＋クロップ                |
| `contain(400, 400)` | 比率を保ちながら指定サイズ内に収まるようリサイズ。余白は背景色で塗りつぶし |
| `crop(300, 200)`    | 指定サイズでクロップ。`x`・`y` 座標も指定可             |

```php theme={null}
$image = $image->resize(800, 600);
$image = $image->resize(width: 800);       // 幅のみ
$image = $image->scale(800, 600);
$image = $image->cover(400, 400);
$image = $image->contain(400, 400, '#ffffff');
$image = $image->crop(300, 200, x: 50, y: 25);
```

### その他の変換

```php theme={null}
$image = $image->orient();            // EXIF の向き情報に従って回転
$image = $image->rotate(90);          // 時計回りに 90° 回転
$image = $image->rotate(90, '#ffffff'); // 背景色を指定して回転
$image = $image->blur(5);             // ぼかし（0〜100）
$image = $image->grayscale();         // グレースケール
$image = $image->sharpen(10);         // シャープ化（0〜100）
$image = $image->flipVertically();    // 上下反転
$image = $image->flipHorizontally();  // 左右反転
```

### 条件付き変換

画像インスタンスは `Conditionable` トレイトをサポートしており、`when` / `unless` で条件付きの変換が可能です。

```php theme={null}
$image = $request->image('avatar')
    ->when($request->boolean('crop'), fn ($image) => $image->cover(400, 400))
    ->unless($request->boolean('preserve_format'), fn ($image) => $image->toWebp());
```

## エンコード

デフォルトでは元のフォーマットでエンコードされます。フォーマットを変換するには以下のメソッドを使います。

```php theme={null}
$image = $image->toWebp();
$image = $image->toJpg();
$image = $image->toJpeg();
```

`quality` メソッドで出力品質（1〜100）を設定できます。

```php theme={null}
$image = $image->toWebp()->quality(80);
```

`optimize` メソッドはフォーマット変換と品質設定のショートカットです。デフォルトは WebP・品質 70 です。

```php theme={null}
$image = $image->optimize();
$image = $image->optimize(format: 'jpg', quality: 85);
```

バイト列・Base64・Data URI として取得することもできます。

```php theme={null}
$bytes   = $image->toBytes();
$base64  = $image->toBase64();
$dataUri = $image->toDataUri();
$bytes   = (string) $image; // 文字列キャスト
```

## 保存

`store` メソッドで画像をファイルシステムディスクに保存します。Laravel は一意なファイル名を自動生成し、保存パスを返します。

```php theme={null}
$path = $request->image('avatar')
    ->cover(400, 400)
    ->store(path: 'avatars');

$path = $request->image('avatar')
    ->cover(400, 400)
    ->store(path: 'avatars', disk: 's3');
```

ファイル名を指定する場合は `storeAs` を使います。

```php theme={null}
$path = $request->image('avatar')
    ->cover(400, 400)
    ->storeAs(path: 'avatars', name: 'avatar.jpg', disk: 'public');
```

`public` 可視性で保存する場合は `storePublicly` / `storePubliclyAs` を使います。

```php theme={null}
$path = $request->image('avatar')
    ->cover(400, 400)
    ->storePublicly(path: 'avatars', disk: 'public');

$path = $request->image('avatar')
    ->cover(400, 400)
    ->storePubliclyAs(path: 'avatars', name: 'avatar.webp', disk: 'public');
```

保存に失敗した場合は `false` を返します。

## 画像情報の取得

`mimeType`・`extension`・`dimensions`・`width`・`height` メソッドで画像の情報を取得できます。これらのメソッドは処理後の画像を対象とします（例：`cover(400, 400)` 後に `width()` を呼ぶと `400` を返します）。

```php theme={null}
$mimeType = $image->mimeType();
$extension = $image->extension();

[$width, $height] = $image->dimensions();
$width  = $image->width();
$height = $image->height();
```

## カスタムドライバー

Laravel の画像マネージャーは `Illuminate\Support\Manager` を継承しており、`extend` メソッドでカスタムドライバーを登録できます。

カスタムドライバーは `Illuminate\Contracts\Image\Driver` インターフェースを実装し、`process` メソッドで元の画像バイト列とパイプラインを受け取り、処理済み画像バイト列を返します。

```php theme={null}
<?php

namespace App\Images;

use Illuminate\Contracts\Image\Driver;
use Illuminate\Image\ImagePipeline;

class VipsDriver implements Driver
{
    public function process(string $contents, ImagePipeline $pipeline): string
    {
        // パイプラインの変換と出力オプションを適用...
        return $contents;
    }

    public function transformUsing(string $transformation, callable $callback): static
    {
        // ハンドラーを保存して処理中に適用できるようにする...
        return $this;
    }
}
```

登録はサービスプロバイダーの `boot` メソッドで行います。

```php theme={null}
use App\Images\VipsDriver;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Image;

public function boot(): void
{
    Image::extend('vips', function (Application $app) {
        return new VipsDriver;
    });
}
```

特定の画像に対してドライバーを指定するには `using` メソッドを使います。

```php theme={null}
$image = $request->image('avatar')
    ->using('vips')
    ->cover(400, 400);
```

## カスタム変換

`Illuminate\Contracts\Image\Transformation` インターフェースを実装したクラスでカスタム変換を定義できます。

```php theme={null}
<?php

namespace App\Images\Transformations;

use Illuminate\Contracts\Image\Transformation;

class Pixelate implements Transformation
{
    public function __construct(
        public readonly int $size,
    ) {}
}
```

ハンドラーの登録はサービスプロバイダーの `boot` メソッドで行います。

```php theme={null}
use App\Images\Transformations\Pixelate;
use Illuminate\Support\Facades\Image;
use Intervention\Image\Interfaces\ImageInterface;

Image::transformUsing('gd', Pixelate::class, function (ImageInterface $image, Pixelate $transformation) {
    return $image->pixelate($transformation->size);
});
```

登録後は `transform` メソッドで適用します。

```php theme={null}
use App\Images\Transformations\Pixelate;

$image = $request->image('avatar')
    ->transform(new Pixelate(12))
    ->store('avatars');
```


## Related topics

- [Singer Info](/jp/packages/laravel-voicevox/engine-api/その他/singer-info.md)
- [Speaker Info](/jp/packages/laravel-voicevox/engine-api/その他/speaker-info.md)
- [Eloquent APIリソース](/jp/eloquent-resources.md)
- [Laravel 11から12へのアップグレードガイド](/jp/blog/upgrade-11-to-12.md)
- [Boostのカスタムエージェントを作る](/jp/advanced/boost-custom-agent.md)
