jackbarham's avatar

Using Image Intervention with Laravel Nova

I'm trying crop images once they upload, then save to newly cropped image to S3. I have all working expect the image cropping.

I don't see anything on the documentation about being able to crop images at the server end, is it this even possible?

I know there's a front-end Nova package for cropping images before upload, but I'd like to process image cropping (ideally with Image Intervention) at the server level.

An example would be:

Avatar::make('Image Large')
    ->hideFromIndex()
    ->disk('s3_image')
    ->storeAs(function (Request $request) {
        Image::make($request->image_large)->fit(280, 720, function ($c) {
            $c->upsize();
        })->encode('jpg', 80);
    })
    ->rules('required')
    ->prunable(),

Has anyone got it working yet?

0 likes
6 replies
jackbarham's avatar

I was having issues. Let me try again, as I might be getting the logic wrong :)

jackbarham's avatar

Hi, @martinbean

I have Image Intervention working and pushing to S3, but I can't save the filename to the table.

this is what I have so far:

// Use AS because Image is already a Nova facade
use Intervention\Image\Facades\Image as Cropper;

- - -

Avatar::make('Image Large')
    ->store(function (Request $request, $model) {
        
        // Create a UUID filename
        $fileName = $this->uuid() . '.jpg';
        
        // Crop with Image Intervention
        $cropped = Cropper::make($request->image_large)->fit(100, 50, function ($c) {
            $c->upsize();
        })->encode('jpg', 80);

        // Store on S3
        Storage::disk('s3_image')->put($fileName, (string) $cropped);

        // Save filename in DB
        $model->update([
            'image_large' => $fileName,
        ]);
    })
    ->rules('required')
    ->prunable(),

All working except the last part, saving the filename.

martinbean's avatar

@jackbarham Did you read the documentation and the example?

As you can see in the example above, the store callback is returning an array of keys and values. These key / value pairs are mapped onto your model instance before it is saved to the database, allowing you to update one or many of the model's database columns after your file is stored.

You need to return an array, as per the example. The model hasn’t been saved yet, so there’s nothing to update.

jackbarham's avatar

Thanks, @martinbean. It wasn't obvious at first, but have it working now.

Avatar::make('Image', 'image_large')
    ->store(function (Request $request, $model) {

        // Create a UUID filename
        $fileSmall = $this->uuid() . '.jpg';
        $fileLarge = $this->uuid() . '.jpg';

        // Crop with Image Intervention
        $imageSmall = Cropper::make($request->image)->fit(200, 100, function ($c) {
            $c->upsize();
        })->encode('jpg', 90);
        $imageLarge = Cropper::make($request->image)->fit(500, 300, function ($c) {
            $c->upsize();
        })->encode('jpg', 90);

        // Store on S3
        Storage::disk('s3_image')->put($fileSmall, (string) $imageSmall);
        Storage::disk('s3_image')->put($fileLarge, (string) $imageLarge);

        return [
            'image_small' => $fileSmall,
            'image_large' => $fileLarge,
        ];
    })
    ->rules('required')
    ->disk('s3_image')
    ->hideFromIndex()
    ->prunable(),
1 like

Please or to participate in this conversation.