ahuson's avatar

Prevent generating oversized media in spatie media library

I am using Spatie media library to manage media in my laravel app. The issue is it generates oversized images even if the uploaded file is small which results in pixelated images.

Below is my model code. Suppose if I upload image of width 700 pixels, it also generates md, lg, and xl images.

How do I prevent media conversions which are greater than the uploaded image's width?


namespace App;

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

class Post extends Model implements HasMedia
{
    use InteractsWithMedia;

    public function registerMediaConversions(Media $media = null) : void
    {
        $this->addMediaConversion('thumb')
            ->width(100);
        $this->addMediaConversion('xs')
            ->width(320);
        $this->addMediaConversion('sm')
            ->width(640);
        $this->addMediaConversion('md')
            ->width(768);
        $this->addMediaConversion('lg')
            ->width(1024);
        $this->addMediaConversion('xl')
            ->width(1280);
    }

    public function registerMediaCollections() : void
    {
        $this->addMediaCollection('images');
    }
}
0 likes
3 replies
Tray2's avatar
Tray2
Best Answer
Level 73

You can put a check on the width.

Something like

if ($this->width > 768) {
$this->addMediaConversion('md')
            ->width(768);
}

if ($this->width > 1024) {
$this->addMediaConversion('lg')
            ->width(1024);
} 

And so on.

Swaz's avatar

In addition to the answer from @Tray2

This page of the docs says you can use methods from the spatie/image manipulation package.

https://spatie.be/docs/laravel-medialibrary/v9/converting-images/defining-conversions

Using FIT_MAX will prevent the image from being resized larger.

https://spatie.be/docs/image/v1/image-manipulations/resizing-images#fit

use Spatie\Image\Manipulations;

public function registerMediaConversions(Media $media = null): void
{
    $this->addMediaConversion('thumb')->fit(Manipulations::FIT_MAX, 100, 100);
    $this->addMediaConversion('xs')->fit(Manipulations::FIT_MAX, 320, 320);
    $this->addMediaConversion('sm')->fit(Manipulations::FIT_MAX, 640, 640);
    $this->addMediaConversion('md')->fit(Manipulations::FIT_MAX, 768, 768);
    $this->addMediaConversion('lg')->fit(Manipulations::FIT_MAX, 1024, 1024);
    $this->addMediaConversion('xl')->fit(Manipulations::FIT_MAX, 1280, 1280);
}

Also, that is a lot of image conversions. You may want to look into the Responsive Images section, it may or may not fit your needs.

https://spatie.be/docs/laravel-medialibrary/v9/responsive-images/getting-started-with-responsive-images

1 like

Please or to participate in this conversation.