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

# Procesamiento de imágenes

> Explica cómo redimensionar, recortar, convertir y guardar imágenes usando la fachada Image de Laravel.

## Introducción

Laravel ofrece una API fluida de procesamiento de imágenes a través de la fachada `Image`. Puedes describir operaciones como redimensionar, recortar, codificar o guardar con una notación coherente en todo el framework.

Internamente utiliza [Intervention Image](https://image.intervention.io/), que soporta tanto la extensión GD como la extensión Imagick de PHP.

```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>
  El procesamiento de imágenes puede consumir mucha CPU y memoria. No proceses imágenes grandes dentro de una petición HTTP; considera hacerlo mediante un [job de cola](/es/queues).
</Warning>

<Info>
  Esta funcionalidad está disponible desde **Laravel v13.20.0**. Si utilizas una versión anterior, actualiza el framework a la última con `composer update`.
</Info>

## Instalación

Antes de usar el procesamiento de imágenes, instala el paquete Intervention Image con Composer.

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

Además, verifica que tienes instalada la extensión GD o Imagick de PHP según el driver que vayas a utilizar.

### Configuración

El archivo de configuración se ubica en `config/image.php`. Si no existe, publícalo con el comando Artisan.

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

El driver por defecto se puede indicar en el archivo de configuración o con la variable de entorno `IMAGE_DRIVER`. Los drivers soportados son `gd` e `imagick`.

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

## Cargar imágenes

La fachada `Image` ofrece métodos para crear una instancia de imagen desde diversas fuentes. El contenido de la imagen se carga de forma perezosa, así que no se lee realmente hasta que se solicita el procesamiento o los bytes.

### Archivo subido

Para obtener una imagen enviada desde una petición, usa el método `image`. Si el archivo no existe, devuelve `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');

    // ...
});
```

Para crearla a partir de una instancia de `UploadedFile`, usa `fromUpload`.

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

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

Para instancias creadas desde una subida, el método `file` te permite recuperar el archivo original.

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

### Archivo del storage

Para crear una instancia a partir de un archivo guardado en un [disco del sistema de archivos](/es/filesystem), usa `fromStorage`. El primer argumento es la ruta y el segundo, el nombre del disco.

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

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

También puedes crearla desde el método `image` de la fachada `Storage`.

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

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

### Otras fuentes

También puedes crear una instancia a partir de bytes, una ruta local, una URL o 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');
```

## Procesar la imagen

Las instancias de imagen son inmutables. Cada método devuelve una nueva instancia con la transformación añadida al pipeline de procesamiento, así que puedes encadenarlas. Las transformaciones se aplican en el orden en que se añaden al pipeline y la codificación se realiza una sola vez al final.

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

### Redimensionado

| Método              | Descripción                                                                                                                     |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `resize(800, 600)`  | Redimensiona al tamaño indicado. Se puede indicar solo el ancho o solo el alto                                                  |
| `scale(800, 600)`   | Reduce manteniendo la proporción hasta caber en las dimensiones indicadas. No amplía                                            |
| `cover(400, 400)`   | Redimensiona y recorta para cubrir por completo las dimensiones indicadas                                                       |
| `contain(400, 400)` | Redimensiona manteniendo la proporción hasta caber en las dimensiones indicadas. Los márgenes se rellenan con el color de fondo |
| `crop(300, 200)`    | Recorta al tamaño indicado. Se pueden indicar las coordenadas `x` e `y`                                                         |

```php theme={null}
$image = $image->resize(800, 600);
$image = $image->resize(width: 800);       // Solo el ancho
$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);
```

### Otras transformaciones

```php theme={null}
$image = $image->orient();            // Rota según la orientación EXIF
$image = $image->rotate(90);          // Rota 90° en sentido horario
$image = $image->rotate(90, '#ffffff'); // Rota con color de fondo
$image = $image->blur(5);             // Desenfoque (0–100)
$image = $image->grayscale();         // Escala de grises
$image = $image->sharpen(10);         // Enfoque (0–100)
$image = $image->flipVertically();    // Voltear verticalmente
$image = $image->flipHorizontally();  // Voltear horizontalmente
```

### Transformaciones condicionales

Las instancias de imagen soportan el trait `Conditionable`, que permite transformaciones condicionales con `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());
```

## Codificación

Por defecto se codifica en el formato original. Para cambiar de formato:

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

Con el método `quality` puedes fijar la calidad de salida (1–100).

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

`optimize` es un atajo para el cambio de formato y el ajuste de calidad. Por defecto usa WebP con calidad 70.

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

También puedes obtener los bytes, Base64 o data URI.

```php theme={null}
$bytes   = $image->toBytes();
$base64  = $image->toBase64();
$dataUri = $image->toDataUri();
$bytes   = (string) $image; // Casteo a cadena
```

## Guardar

Con el método `store` guardas la imagen en un disco del sistema de archivos. Laravel genera automáticamente un nombre único y devuelve la ruta de guardado.

```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');
```

Para especificar el nombre de archivo, usa `storeAs`.

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

Para guardar con visibilidad `public`, usa `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');
```

Si falla el guardado, se devuelve `false`.

## Obtener información de la imagen

Con los métodos `mimeType`, `extension`, `dimensions`, `width` y `height` puedes consultar la información de la imagen. Estos métodos operan sobre la imagen ya procesada (por ejemplo, tras `cover(400, 400)`, llamar a `width()` devuelve `400`).

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

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

## Drivers personalizados

El gestor de imágenes de Laravel extiende `Illuminate\Support\Manager`, así que puedes registrar drivers personalizados con el método `extend`.

Un driver personalizado implementa la interfaz `Illuminate\Contracts\Image\Driver`, y en el método `process` recibe los bytes originales y el pipeline y devuelve los bytes procesados.

```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
    {
        // Aplica las transformaciones y opciones de salida del pipeline...
        return $contents;
    }

    public function transformUsing(string $transformation, callable $callback): static
    {
        // Guarda el handler para poder aplicarlo durante el procesamiento...
        return $this;
    }
}
```

Regístralo en el método `boot` de un service provider.

```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;
    });
}
```

Para especificar el driver para una imagen concreta, usa `using`.

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

## Transformaciones personalizadas

Puedes definir transformaciones personalizadas con una clase que implemente la interfaz `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,
    ) {}
}
```

Registra el handler en el método `boot` de un service provider.

```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);
});
```

Una vez registrado, aplícalo con `transform`.

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

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


## Related topics

- [Driver de Amazon Bedrock para Laravel AI SDK](/es/packages/laravel-amazon-bedrock.md)
- [Laravel Sail](/es/sail.md)
- [Laravel AI SDK](/es/ai-sdk.md)
- [Patrón Pipeline](/es/advanced/pipeline.md)
- [Atributos PHP en controladores](/es/advanced/controller-attributes.md)
