php 带有 Laravel 5.4 存储的图像干预

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40025456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:05:52  来源:igfitidea点击:

Image Intervention w/ Laravel 5.4 Storage

phplaravellaravel-5.3laravel-5.4

提问by wizardzeb

I'm using the storage facade to store a avatar which works fine, but I want to resize my image like I did in previous versions of laravel. How can I go about doing this? Here is what I have so far (doesn't work)

我正在使用存储外观来存储一个工作正常的头像,但我想像在以前版本的 laravel 中那样调整我的图像大小。我该怎么做呢?这是我到目前为止所拥有的(不起作用)

  $path   = $request->file('createcommunityavatar');
  $resize = Image::make($path)->fit(300);
  $store  = Storage::putFile('public/image', $resize);
  $url    = Storage::url($store);

Error Message:

错误信息:

  Command (hashName) is not available for driver (Gd).

回答by Leonid Shumakov

You're trying to pass into putFile wrong object. That method expects File object (not Image).

您正试图传入 putFile 错误的对象。该方法需要 File 对象(不是 Image)。

$path   = $request->file('createcommunityavatar');

// returns \Intervention\Image\Image - OK
$resize = Image::make($path)->fit(300);

// expects 2nd arg - \Illuminate\Http\UploadedFile - ERROR, because Image does not have hashName method
$store  = Storage::putFile('public/image', $resize);

$url    = Storage::url($store);

Ok, now when we understand the main reason, let's fix the code

好的,现在我们了解了主要原因,让我们修复代码

// returns Intervention\Image\Image
$resize = Image::make($path)->fit(300)->encode('jpg');

// calculate md5 hash of encoded image
$hash = md5($resize->__toString());

// use hash as a name
$path = "images/{$hash}.jpg";

// save it locally to ~/public/images/{$hash}.jpg
$resize->save(public_path($path));

// $url = "/images/{$hash}.jpg"
$url = "/" . $path;

Let's imagine that you want to use Storage facade:

假设您要使用 Storage 门面:

// does not work - Storage::putFile('public/image', $resize);

// Storage::put($path, $contents, $visibility = null)
Storage::put('public/image/myUniqueFileNameHere.jpg', $resize->__toString());

回答by Jeffrey

The putmethod works with the Image intervention output. The putFilemethod accepts either an Illuminate\Http\File or Illuminate\Http\UploadedFile instance.

方法适用于图像输出周期。该PUTFILE方法接受任一种照亮\ HTTP \文件或照亮\ HTTP \ UploadedFile的实例。

$photo = Image::make($request->file('photo'))
  ->resize(400, null, function ($constraint) { $constraint->aspectRatio(); } )
  ->encode('jpg',80);

Storage::disk('public')->put( 'photo.jpg', $photo);

The above code resizes the uploaded file to 400px width while holding the aspect ratio. Then encodes to jpg at 80% quality. The file is then stored to the public disc. Note you must provide a filename, not just the directory.

上面的代码在保持纵横比的同时将上传的文件调整为 400px 宽度。然后以 80% 的质量编码为 jpg。然后将该文件存储到公共光盘。请注意,您必须提供文件名,而不仅仅是目录。

回答by Clément Baconnier

Using Laravel 5.8

使用 Laravel 5.8

I had a similar issue when trying to readan image file with Imagewhen this one was savedand loadedwith Storage.
Beside all the answers I wasn't sure why it wasn't working.

我在尝试读取图像文件Image时遇到了类似的问题,当这个文件被保存加载Storage
除了所有的答案,我不确定为什么它不起作用。



Exception when Imagewas trying to read the file

Image尝试读取文件时出现异常

Intervention\Image\Exception\NotReadableException : Unable to init from given binary data.

Intervention\Image\Exception\NotReadableException:无法从给定的二进制数据进行初始化。

Short answer

简答

Adding ->encode()solved the issue

添加->encode()解决了问题

http://image.intervention.io/api/encode

http://image.intervention.io/api/encode

Scenario

设想

Basically I had a test like this

基本上我有这样的测试

Storage::fake();

$photo = factory(Photo::class)->create();    
$file = \Image::make(
    UploadedFile::fake()->image($photo->file_name, 300, 300)
);

Storage::disk($photo->disk)
    ->put(
        $photo->fullPath(),
        $file
    );

And in the controller I had something like this

在控制器中我有这样的东西

return \Image::make(
    Storage::disk($photo->disk)
        ->get(
            $photo->fullPath()
        )
)->response();

Solution

解决方案

After investigation I realized that any file created by Imageand saved by the Storagehad a size of 0 octets. After looking at all the solutions from this post and few hours after, I noticed everyone was using encode()but no one did mention it was that. So I tried and it worked.

经过调查,我意识到由 创建Image和保存的任何文件Storage的大小为0 八位字节。在查看了这篇文章和几个小时后的所有解决方案后,我注意到每个人都在使用,encode()但没有人提到它。所以我试过了,它奏效了。

Investigating a bit more, Imagedoes, in fact, encodeunder the hood before saving. https://github.com/Intervention/image/blob/master/src/Intervention/Image/Image.php#L146

多研究一点,Image实际上,在保存之前会在引擎盖下进行编码https://github.com/Intervention/image/blob/master/src/Intervention/Image/Image.php#L146

So, my solution was to simple doing this

所以,我的解决方案是简单地这样做

$file = \Image::make(
    \Illuminate\Http\UploadedFile::fake()->image('filename.jpg', 300, 300)
)->encode();

\Storage::put('photos/test.jpg', $file);

testable in Tinker, It will create a black image

可在Tinker 中测试,它将创建一个黑色图像

回答by Md. Zubaer Ahammed

I do it this way:

我这样做:

  1. Resize and save image somewhere (such as in the public folder).
  2. Create a new File and pass it to Laravel filesystem functions (such as putFileAs).
  3. Delete temporary intervention file
  1. 调整图像大小并将其保存在某处(例如在公共文件夹中)。
  2. 创建一个新文件并将其传递给 Laravel 文件系统函数(例如 putFileAs)。
  3. 删除临时干预文件

Note: Of course you can modify it according to your needs.

注:当然您可以根据需要进行修改。

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

$image = Image::make($file);

$image->resize(570, 326, function ($constraint) {
    $constraint->aspectRatio();
});

$thumbnail_image_name = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME).'.'.$file->getClientOriginalExtension();

$image->save(public_path('images/'.$thumbnail_image_name));

$saved_image_uri = $image->dirname.'/'.$image->basename;

//Now use laravel filesystem.
$uploaded_thumbnail_image = Storage::putFileAs('public/thumbnails/'.$portfolio_returned->id, new File($saved_image_uri), $thumbnail_image_name);

//Now delete temporary intervention image as we have moved it to Storage folder with Laravel filesystem.
$image->destroy();
unlink($saved_image_uri);

回答by Jesse van der Pluijm

The cleanest solution I could find—using the native Storagefacade—is the following. I can confirm that this works in Laravel 5.7, using intervention/imageversion 2.4.2.

我能找到的最干净的解决方案——使用原生Storage外观——如下。我可以确认这在 Laravel 5.7 中有效,使用intervention/image版本 2.4.2。

$file = $request->file('avatar');
$path = $file->hashName('public/avatars');
$image = Image::make($file)->fit(300);
Storage::put($path, (string) $image->encode());

$url = Storage::url($path);

回答by Govind Samrow

I've done it with following way, its simple and without any path confusion :

我用以下方式完成了它,它很简单,没有任何路径混淆:

//Get file
$path= $request->file('createcommunityavatar');

// Resize and encode to required type
$img = Image::make($file)->fit(300)->encode('jpg');

//Provide own name
$name = time() . '.jpg';

//Put file with own name
Storage::put($name, $img);

//Move file to your location 
Storage::move($name, 'public/image/' . $name);

回答by Rob

Make sure to add use Illuminate\Http\File;to top of your file for this to work, and read through the documentation section Automatic Streaming.

确保添加use Illuminate\Http\File;到文件顶部以使其工作,并通读文档部分Automatic Streaming

This assumes you want all jpegs

这假设您想要所有 jpeg

$path   = $request->file('createcommunityavatar');
$resize = Image::make($path)->fit(300)->encode('jpg');
$filePath = $resize->getRealPath() . '.jpg';
$resize->save($filePath);
$store  = Storage::putFile('public/image', new File($resize));
$url    = Storage::url($store);

This is how I am doing it in my application with comments to help

这就是我在我的应用程序中使用注释来帮助它的方式

// Get the file from the request
$requestImage = request()->file('image');

// Get the filepath of the request file (.tmp) and append .jpg
$requestImagePath = $requestImage->getRealPath() . '.jpg';

// Modify the image using intervention
$interventionImage = Image::make($requestImage)->resize(125, 125)->encode('jpg');

// Save the intervention image over the request image
$interventionImage->save($requestImagePath);

// Send the image to file storage
$url = Storage::putFileAs('photos', new File($requestImagePath), 'thumbnail.jpg');

return response()->json(['url' => $url]);

回答by Himanshu Sharma

Try updating the GD extension for the current php version.

尝试更新当前 php 版本的 GD 扩展。

If that doesn't help, try saving the resized image on local disk and using Storage::putFile.

如果这没有帮助,请尝试将调整大小的图像保存在本地磁盘上并使用 Storage::putFile。

You may delete the file once it has been uploaded to your storage path.

一旦文件上传到您的存储路径,您就可以删除该文件。

The second parameter to your putFile method is an instance of the Image Intervention class. You need to pass this as the second parameter to the putFile method.

putFile 方法的第二个参数是 Image Intervention 类的一个实例。您需要将此作为第二个参数传递给 putFile 方法。

$resize->save($absolutePath . 'small/' . $imageName);

回答by Jones03

You can't store an \Intervention\Image\Image object directly with the Laravel 5 filesystem. What you can do is resize the image from your request, and save it under the same tmp path. Then just store the uploaded (overwritten) file to the filesystem.

您不能直接使用 Laravel 5 文件系统存储 \Intervention\Image\Image 对象。您可以做的是根据您的请求调整图像大小,并将其保存在相同的 tmp 路径下。然后只需将上传(覆盖)的文件存储到文件系统。

Code:

代码:

$image  = $request->file('createcommunityavatar');
//resize and save under same tmp path
$resize = Image::make($image)->fit(300)->save();
// store in the filesystem with a generated filename
$store  = $image->store('image', 'public');
// get url from storage
$url    = Storage::url($store);