使用 Laravel 干预图像上传到 S3 returns 布尔值而不是路径

Uploading to S3 with Laravel Intervention image returns boolean and not path

我在 Laravel 中上传图片时遇到问题。有时图像需要重新定向 - 当使用干预图像执行此操作时,它只是 returns 一个布尔值而不是 s3 中图像的路径。在没有干预图像的情况下使用它时它工作正常

我试过exif读取数据并使用imagerotate无济于事,它出错了

我运行以下

$image = $request->file('photo');
$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');
dd($path); // /users/1/posts/39grjigrje.jpg

$path 变量很好,是 s3 路径,但是 运行ning:

$image = $request->file('photo');
$image = \Image::make($image);
$image->orientate();
$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');
dd($path); // true

$path 变量只是一个布尔值,而不是 return 存储的文件路径

我希望有一条路径,例如/images/1/kfjeieuge.jpg 当我不使用干预图像时我得到,当我使用干预时我得到一个布尔值。

几年前我也遇到过同样的问题。我通过以下步骤解决了这个问题:

1.You 可能必须在对图像进行干预操作后对其进行编码。 要实现编码,请参阅有关流方法的文档:Create encoded image stream

Encodes the current image in given format and given image quality and creates new PSR-7 stream based on image data.

$image = Image::make(request()->file('image'))->orientate()->encode('jpg');

2.And 然后用流存储它

$path = Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image->stream(),'public');

这应该可以实现您的 objective。

您可以按照下面的方法解决link

https://laracasts.com/discuss/channels/laravel/saving-an-intervention-image-instance-into-amazon-s3

$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image->stream()->__toString(), 'public');

更新:7 月 5 日

如果您查看源代码,它应该 return bool only

https://github.com/laravel/framework/blob/c7bdf66062af3c63648f7c29591476e6db92c885/src/Illuminate/Filesystem/FilesystemAdapter.php#L192

/**
     * Write the contents of a file.
     *
     * @param  string  $path
     * @param  string|resource  $contents
     * @param  mixed  $options
     * @return bool
     */
    public function put($path, $contents, $options = [])
    {
        $options = is_string($options)
                     ? ['visibility' => $options]
                     : (array) $options;
        // If the given contents is actually a file or uploaded file instance than we will
        // automatically store the file using a stream. This provides a convenient path
        // for the developer to store streams without managing them manually in code.
        if ($contents instanceof File ||
            $contents instanceof UploadedFile) {
            return $this->putFile($path, $contents, $options);
        }
        return is_resource($contents)
                ? $this->driver->putStream($path, $contents, $options)
                : $this->driver->put($path, $contents, $options);
    }

如您所见,Streamfile 的处理方式不同

理想的做法是使用 url 函数来获取 url

Storage::disk('s3')->url($filename)

在第一个例子中:

$image = $request->file('photo');
$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 
'public');

$request->file('photo') 文件将 return Illuminate\Http\UploadedFile class 的实例。您可以在此处查看文档 link.

正如 Tarun 所说 put 方法检查 Illuminate\Http\UploadedFile class 的实例。这样的话,就上传成功了。

在第二个例子中:

$image = $request->file('photo');
$image = \Image::make($image); //here
$image->orientate();
$path = \Storage::disk('s3')->put('users/' . \Auth::id() . '/posts', $image, 'public');

您正在用实例 Image class 覆盖 $image 变量(第二行)。这是错误的。您需要通过 Stream 或 file.

试试下面的代码:

$image = $request->file('photo');
$image = \Image::make($image); //here
$image->orientate()->encode('jpg');
$filename = time() . '.jpg';
$path = \Storage::disk('s3')->put('users/' . \Auth::id() . '/posts/'.$filename, $image->getEncoded(), 'public');

试试这个

$image = \Image::make($request->file('photo')->getRealpath());
$image->orientate();


$image->encode('jpg');
 OR
$image->response('jpg', 100);


$path = \Storage::disk('s3')->put('users/'.\Auth::id().'/posts', $image, 'public');