【问题标题】:Image Intervention w/ Laravel 5.4 Storage带有 Laravel 5.4 存储的图像干预
【发布时间】:2016-10-13 15:42:22
【问题描述】:

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

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

错误信息:

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

【问题讨论】:

  • 嗨试试这个 Image::make($path)->resize(300, 300);
  • 这给了我和以前一样的错误。 Command (hashName) is not available for driver (Gd).
  • 这个问题解决了吗?
  • @CriticalTheWizard 将驱动程序更改为imagick 没有帮助。现在我得到Command (hashName) is not available for driver (Imagick).

标签: php laravel laravel-5.3 laravel-5.4


【解决方案1】:

您试图将错误的对象传递给 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);

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

// 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;

假设你想使用 Storage 门面:

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

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

【讨论】:

  • 上面的代码工作得很好,需要注意的是:md5($resize->__toString()); 总是为同一个文件返回相同的哈希值,这在某些情况下可能会出现问题。在我的解决方案中,我已将其替换为 $now = Carbon::now()->toDateTimeString(); $hash = md5($image->__toString().$now);
【解决方案2】:

put 方法适用于图像干预输出。 putFile 方法接受 Illuminate\Http\File 或 Illuminate\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);

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

【讨论】:

  • 谢谢!很有帮助。请注意,encode 调用是必需的,否则输出将被破坏。
  • 你也可以这样使用它:Storage::disk('public')->put( $request->file('photo')->hashName(), $photo);
  • 对我真的很有帮助
【解决方案3】:

使用 Laravel 5.8

我在尝试使用Image读取图像文件时遇到了类似的问题,而该图像文件是保存加载使用@987654325 @.
除了所有答案之外,我不确定为什么它不起作用。


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

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

简答

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

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

场景

基本上我有过这样的测试

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
    );

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

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

解决方案

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

再调查一下,Image 实际上会在保存之前在后台编码https://github.com/Intervention/image/blob/master/src/Intervention/Image/Image.php#L146

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

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

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

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

【讨论】:

  • stackoverflow.com/a/43700717/2311074的解决方案相同
  • 在上传 base64 解码图像文件并使用存储存储时也可以使用。没有使用 encode() 函数,我使用Storage::put($file_path, base64_encode($uploadedFile); 时没有上传。最后使用干预图像和编码功能,它工作了。
【解决方案4】:

我能找到的最简洁的解决方案——使用原生的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);

【讨论】:

  • 我使用您的示例收到下一个错误(我正在使用 xampp、php8 和 laravel8)消息:“file_put_contents(C:\\xampp\\htdocs\\xxxxxxxxxxx\\storage\\app \\public):无法打开流:权限被拒绝"
【解决方案5】:

我是这样做的:

  1. 调整图像大小并将图像保存在某处(例如公共文件夹中)。
  2. 创建一个新文件并将其传递给 Laravel 文件系统函数(例如 putFileAs)。
  3. 删除临时干预文件

注意:当然你可以根据自己的需要进行修改。

$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);

【讨论】:

  • 它工作得很好。这也应该是公认的答案。
【解决方案6】:

我通过以下方式完成了它,它简单且没有任何路径混乱:

//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);

【讨论】:

  • $path = $request->file() 应该是$file = $request->file(),对吧?
【解决方案7】:

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

假设您想要所有 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);

这就是我在我的应用程序中使用 cmets 来提供帮助的方式

// 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]);

【讨论】:

  • 你是说$filePath = $resize->getRealPath() . '.jpg';
  • 我在全新安装的 laravel 5.3.* 上进行了尝试,这很有效。你试过了吗?
  • 你在这里使用什么样的新文件? http 文件还是门面文件?
【解决方案8】:

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

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

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

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

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

【讨论】:

    【解决方案9】:

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

    代码:

    $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);
    

    【讨论】:

      【解决方案10】:

      在我的情况下,错误是由在图像实例上调用 hashName 方法引起的。

          //initially
          $image = Image::make(request('image')->getRealPath());
          $filename = $image->hashName();
      
          //to fix the error
          $image = Image::make(request('image')->getRealPath());
          $filename = request('image')->hashName();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-11
        • 1970-01-01
        • 1970-01-01
        • 2015-04-10
        • 1970-01-01
        • 2016-09-05
        • 1970-01-01
        • 2017-01-06
        相关资源
        最近更新 更多