3

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

Spectr
  • 762
  • 8
  • 28
  • What is your question exactly? – jarmod Jan 07 '21 at 13:25
  • @jarmod How to get correct public url for uploaded image – Spectr Jan 07 '21 at 14:34
  • If you uploaded the image to S3, then you know the S3 region, bucket, and object key, which is all you need to create the URL. You [construct it yourself](https://stackoverflow.com/questions/44400227/how-to-get-the-url-of-a-file-on-aws-s3-using-aws-sdk/44401684#44401684). – jarmod Jan 07 '21 at 14:43
  • @jarmod with this package I can't get the image URL. Actually I get url, but it's not a public. That's the question – Spectr Jan 07 '21 at 15:23

2 Answers2

1

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.

sykez
  • 1,606
  • 10
  • 10
0

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());
}
Hasan bd
  • 49
  • 7