> ## 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 Facade 進行圖片的縮放、裁切、格式轉換與儲存。

## 簡介

Laravel 透過 `Image` Facade 提供流暢的圖片加工 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 請求中執行，建議放在[佇列 Job](/zh-TW/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` Facade 提供多種方法從不同來源建立圖片實例。圖片內容為延遲載入，僅在真正處理或要求 byte 序列時才會實際載入。

### 上傳的檔案

從請求取得上傳圖片可用 `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();
```

### 儲存空間中的檔案

要從[檔案系統磁碟](/zh-TW/filesystem)所儲存的檔案建立圖片實例，可使用 `fromStorage`。第一個參數為檔案路徑，第二個為磁碟名稱。

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

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

也可透過 Storage Facade 的 `image` 方法建立。

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

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

### 其他來源

亦可從 byte、本機路徑、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` trait，可用 `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);
```

也可以取為 byte、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` 方法接收原始圖片 byte 與管線，並回傳處理後的圖片 byte。

```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
    {
        // 保存 handler 以於處理中套用...
        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` 方法中註冊 handler：

```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

- [Laravel AI SDK](/zh-TW/ai-sdk.md)
- [Eloquent API 資源](/zh-TW/eloquent-resources.md)
- [通知 Channel - LINE SDK for Laravel](/zh-TW/packages/laravel-line-sdk/notification.md)
- [HTTP 測試](/zh-TW/http-tests.md)
- [Laravel MCP](/zh-TW/mcp.md)
