Last active
October 29, 2022 14:14
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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