Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

How to Generate Image Conversions with Spatie Laravel Media Library

A Laravel site that stores uploaded images often needs smaller versions or versions with different dimensions for cards, thumbnails, and other layouts. Spatie Laravel Media Library makes these versions, called conversions, from media files attached to an Eloquent model. Each conversion is a separate file created by changing the image, for example by resizing or sharpening it.

To create a conversion, implement HasMedia on your model and add InteractsWithMedia. Then define a named conversion in registerMediaConversions. Media Library runs the conversion when you add a supported file. By default, it queues that work. A queue worker must process the job before the converted file is available.

Define a conversion on the model

Add registerMediaConversions to the model that owns the uploaded media. The method names each conversion and specifies the image changes to apply.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

class Product extends Model implements HasMedia
{
    use InteractsWithMedia;

    public function registerMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('card')
            ->width(368)
            ->height(232)
            ->sharpen(10);
    }
}

The name card identifies the generated file when you retrieve it. The model setup documentation explains which interface and trait your model needs. The conversion documentation explains that Media Library uses the spatie/image package for these changes, so you can call that package’s manipulation methods, such as width, height, sharpen, and fit.

When you add a supported file to the model’s media library, Media Library runs the defined conversions. Supported types include common image formats, PDF, and video. PDF, SVG, and video files need extra software, such as Imagick, Ghostscript, or FFmpeg; the image generator documentation lists what each type requires. Conversion files use JPG by default. Call format('webp') to choose another output format, or keepOriginalImageFormat() to use the original format.

To limit a conversion to a particular media collection, chain performOnCollections:

$this->addMediaConversion('card')
    ->width(368)
    ->height(232)
    ->performOnCollections('images');

Use the same collection name here and when you add the media.

Choose when conversions run

Media Library queues conversions by default, so a queue worker processes them outside the upload request. The conversion file does not appear until a worker processes its job. Laravel Media Library’s setup documentation explains the queue_conversions_by_default setting.

Call nonQueued() to make Media Library generate a conversion during the current request:

$this->addMediaConversion('small')
    ->width(200)
    ->nonQueued();

The request waits until the conversion finishes. If the configuration disables queuing by default, call queued() on a conversion that should still use the queue.

deferred() runs a conversion after Laravel sends the response. The same PHP process does the work, so its worker stays busy until the conversion finishes. Use a queue for conversions that would keep the worker busy for too long.

Retrieve the converted file

Pass the conversion name to the media object’s URL method:

$media = $product->getFirstMedia('images');

$url = $media?->getUrl('card');

Use the collection name that holds the file in getFirstMedia. When you know the collection and want its first file’s URL, call getFirstMediaUrl('images', 'card'). Media Library also provides getPath to return a file path and getTemporaryUrl to create temporary URLs for S3 storage. See the retrieval documentation for other available methods.

A queued conversion might not exist yet when your code requests its URL. Check its status with hasGeneratedConversion before using the converted file:

if ($media?->hasGeneratedConversion('card')) {
    $url = $media->getUrl('card');
}

If a conversion is unavailable, Media Library’s available-URL methods can return another conversion or the original file.

Use model data carefully

A conversion definition can use model properties, but Media Library needs the model instance to read them. If a conversion uses those properties, set $registerMediaConversionsUsingModelInstance = true on the model. The library notes that this can add database queries because it must retrieve the model for each media item. For fixed sizes and formats, define the conversion without using model data.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *