> ## 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 请求中，建议作为[队列任务](/zh-CN/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();
```

### 存储文件

要从存储在[文件系统磁盘](/zh-CN/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` 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);
```

也可以以字节序列、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

- [用于 Laravel AI SDK 的 Amazon Bedrock 驱动](/zh-CN/packages/laravel-amazon-bedrock.md)
- [Laravel AI SDK](/zh-CN/ai-sdk.md)
- [并发处理](/zh-CN/concurrency.md)
- [错误处理](/zh-CN/error-handling.md)
- [Laravel Head — 文档 <head> 管理包](/zh-CN/blog/laravel-head-introduction.md)
