Skip to content

Instantly share code, notes, and snippets.

@eugenefvdm
Last active October 29, 2022 14:14
Show Gist options
  • Save eugenefvdm/b2b4019014fe3e88f1c5acce6740ab69 to your computer and use it in GitHub Desktop.
Save eugenefvdm/b2b4019014fe3e88f1c5acce6740ab69 to your computer and use it in GitHub Desktop.
The PHP Intervention library is used to resize an image and center / crop it on a canvas and encode / save it as .webp. The original image is kept. Works with Filamentphp and Livewire
<?php
namespace App\Traits;
use App\Services\ImageService;
use Illuminate\Database\Eloquent\Model;
trait ImageCompression
{
protected static function bootImageCompression(): void
{
static::creating(function (Model $model) {
// At this point Livewire is initialized and we have access to the temporary file...
$filepondFilename = $model->image;
$compressedImage = ImageService::compress($model);
// Swap file names
$model->original_image = $filepondFilename;
$model->image = $compressedImage;
});
static::updating(function (Model $model) {
$model->image = ImageService::compress($model);
});
}
}
<?php
namespace App\Services;
use Spatie\Valuestore\Valuestore;
use Intervention\Image\Facades\Image;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class ImageService
{
/**
* Generic routine to compress images on creating and updating. It uses
* Intervention library will be called to resize and upsize to a
* certain aspect ratio based on X and Y dimensions.
*
* Should be used by a model observer
*
* A filesystem called 'blog' is used to retrieve the correct the path
*/
public static function compress(Model $model, $xSize = 640, $ySize = 480)
{
if (!$model->image) {
return;
}
$retrievedImage = Storage::disk('blog')->get($model->image);
$croppedImage = Image::make($retrievedImage);
$croppedImage->resize($xSize, $ySize, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
// Center on a canvas
$canvas = Image::canvas($xSize, $ySize);
$canvas->insert($croppedImage, 'center');
// Strip extension from filename
// attachment_file_names is internal to Filepond and Filamentphp
// Intervention automatically encodes the file if it is saved as a .webp file
$filename = pathinfo($model->attachment_file_names, PATHINFO_FILENAME).'-'.time().'.webp';
$path = config('filesystems.disks.blog.root').'/';
$croppedImage->save($path.$filename);
return $filename;
}
}
@eugenefvdm
Copy link
Author

I'm cross referencing this gist which does something in the sames lines for reproducing the square block effect of Instagram: https://gist.github.com/MicrowaveDev/6e648bbfe5c1ce1414771cdf3e852f2b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment