First-Party Image Processing in Laravel 13.20
Laravel #Laravel #Image Processing #Laravel 13 #Eloquent #Queue

First-Party Image Processing in Laravel 13.20

3 min read Mohamed Said Mohamed Said

Laravel 13.20.0, released on July 15, 2026, is a notable minor release that brings first-party image processing directly into the framework alongside several quality-of-life improvements for routing, sessions, Eloquent, and queues.

First-Party Image Processing with the Image Facade

The headline feature is the new Illuminate\Image component. It provides an immutable, driver-based API for common image operations — resizing, cropping, format conversion, and storage — without requiring a third-party wrapper package.

Because every transformation returns a new instance, you can branch from a single source image to produce multiple variants without side effects:

$image = $request->image('photo');

$image->cover(200, 200)->toWebp()->store('thumbnails');
$image->grayscale()->toWebp()->store('grayscale');

Loading Images

You can create an Image instance from uploads, paths, URLs, raw bytes, base64 strings, or a storage disk:

$request->image('avatar')->cover(200, 200)->toWebp()->store('avatars');

Image::fromPath('/path/to/photo.jpg');
Image::fromUrl('https://example.com/photo.jpg');
Image::fromBytes($bytes);
Image::fromStorage('photos/avatar.jpg', 's3');
Storage::disk('s3')->image('photos/avatar.jpg');

Available Transformations

The API covers the most common operations:

$image->cover(200, 200);
$image->contain(800, 600);
$image->resize(1024, 768);
$image->rotate(90);
$image->blur(10);
$image->sharpen(10);
$image->grayscale();
$image->flip();
$image->orient(); // Applies EXIF rotation

$image->toWebp();
$image->toJpg()->quality(80);
$image->optimize(); // WebP at quality 70

$image->width();
$image->height();
$image->mimeType();

Drivers

Two drivers ship out of the box — GD and Imagick — both backed by Intervention Image v4. You can select a driver per image instance and override how a driver handles a specific transformation:

$image->usingImagick();
$image->usingGd();

Intervention Image is a suggested dependency, so you must install it before using the facade:

composer require intervention/image

#[WithoutMiddleware] Controller Attribute

A new #[WithoutMiddleware] PHP attribute complements the existing #[Middleware] attribute. Apply it to individual controller methods to exclude middleware that is attached at the class level:

#[Middleware(EnsureTokenIsValid::class)]
class UserController
{
    public function index() { /* middleware applies */ }

    #[WithoutMiddleware(EnsureTokenIsValid::class)]
    public function profile() { /* middleware excluded */ }
}

Matching uses ReflectionAttribute::IS_INSTANCEOF, so subclasses of the excluded middleware are also excluded.

Redis Session Prefix

Applications that share a Redis instance for both cache and sessions can now configure a dedicated prefix in config/session.php:

'prefix' => env('SESSION_PREFIX', Str::slug(env('APP_NAME', 'laravel')).'-session-'),

The cache store is cloned before the session prefix is applied, so cache keys are unaffected.

Quiet Bulk Increments on Eloquent

Two new methods — incrementEachQuietly() and decrementEachQuietly() — update multiple columns at once while suppressing model events:

$user->incrementEachQuietly(['posts_count' => 1, 'points' => 10]);
$user->decrementEachQuietly(['credits' => 3, 'tokens' => 2]);

Enums as WithoutOverlapping Queue Keys

The WithoutOverlapping job middleware now accepts a PHP enum directly as its key, removing the need to manually convert enum values to strings.

Other Improvements

  • beforePushing() / afterPushing() callbacks on QueueFake
  • Storage::assertEmpty() added to the Storage facade
  • make:migration generates collision-free, ordered timestamp prefixes
  • #[SensitiveParameter] applied to parameters carrying secrets to keep them out of stack traces
  • Str::containsAll() no longer returns true for an empty needles array
  • Fixes for BelongsToMany::touch() when the related key is not id

Key Takeaways

  • Laravel 13.20 ships a native Image facade — no more mandatory third-party image packages.
  • The image API is immutable; every transformation returns a new instance.
  • GD and Imagick drivers are included; intervention/image must be installed separately.
  • #[WithoutMiddleware] brings route-group exclusion behavior to controller attributes.
  • A new SESSION_PREFIX env variable isolates session keys in a shared Redis keystore.
  • incrementEachQuietly() and decrementEachQuietly() fill a long-standing Eloquent gap.

Source: Laravel News — First-Party Image Processing in Laravel 13.20

Found this useful?

Frequently Asked Questions

3 questions
Q01 Do I need to install a separate package to use the new Image facade in Laravel 13.20?
Yes. The image component depends on Intervention Image v4, which is listed as a suggested dependency rather than a required one. Run `composer require intervention/image` before using the `Image` facade or `$request->image()` helper.
Q02 How does the immutable image API work in practice?
Every transformation method returns a new `Image` instance rather than modifying the original. This means you can call multiple transformation chains on the same source image — for example, generating a thumbnail and a grayscale variant — without one chain affecting the other.
Q03 Will setting a Redis session prefix affect my existing cache keys?
No. Laravel clones the cache store before applying the session prefix, so your cache keys remain unchanged. The `SESSION_PREFIX` option is opt-in and only affects session keys stored in Redis.

Continue reading

More Articles

View all