Image Intervention w/ Laravel 5.4 Storage Image Intervention w/ Laravel 5.4 Storage php php

Image Intervention w/ Laravel 5.4 Storage


You're trying to pass into putFile wrong object. That method expects File object (not 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:

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


The put method works with the Image intervention output.The putFile method accepts either an Illuminate\Http\File or Illuminate\Http\UploadedFile instance.

$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.


Using Laravel 5.8

I had a similar issue when trying to read an image file with Image when this one was saved and loaded with Storage.
Beside all the answers I wasn't sure why it wasn't working.


Exception when Image was trying to read the file

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

Short answer

Adding ->encode()solved the issue

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 Image and saved by the Storage had 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.

Investigating a bit more, Image does, in fact, encode under the hood before saving.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