Resize image and store it to s3

Viewed 395

Default image upload process in my app like this.

Get image from request and store it to s3 and a local variable.

$path = $request->file("image")->store("images", "s3");

After this I make it public.

Storage::disk("s3")->setVisibility($path, 'public');

And store to DB like this.

   $variable = ModelName::create([
      "image" => basename($path),
      "image_url" => Storage::disk("s3")->url($path),

But how to resize the image before store it to s3?

I try to write like this

    $extension = $request->file('image')->getClientOriginalExtension();
    $normal = Image::make($request->file('image'))->resize(160, 160)->encode($extension);
    $filename = md5(time()).'_'.$request->file('image')->getClientOriginalName();
    $img = Storage::disk('s3')->put('/images/'.$filename, (string)$normal, 'public');

And then

    "image" => basename($filename ),
    "image_url" => Storage::disk("s3")->url($img),

This works except one thing. I can't get URL (to store DB) for uploaded image.

How to get correct public url for uploaded image?

Note:I use Intervention Image package

2 Answers

Storage::put() would only return the path if it's an instance of File or UploadedFile (source). In this case $normal isn't, so put() would return a boolean instead. Also, using getClientOriginalExtension() probably isn't a good idea since it's not considered a safe value (source).

So here's a bit improved version:

$filename = $request->file('file')->hashname();
$image = Image::make($request->file('file'))->resize(160, 160);
Storage::disk('s3')->put('/images/'.$filename, $image->stream(), 'public');
$url = Storage::disk('s3')->url('/images/'.$filename);

You can now save $url and $filename into your db.

You can try my code snippet.

$file = $request->file('image');

$fileName = md5(time()).'.'.$file->getClientOriginalExtension();

/** @var Intervention $image */
$image = Image::make($file);
if ($image->width() > ($maxWidth ?? 500)) {
    $image = $image->resize(500, null, function ($constraint) {$constraint->aspectRatio();});
}

$image = $image->stream();

try {
    /** @var Storage $path */
    Storage::disk('s3')->put(
        $dir . DIRECTORY_SEPARATOR . $fileName, $image->__toString()
    );
} catch (\Exception $exception) {
    Log::debug($exception->getMessage());
}
Related