Взаимодействие изображений с Laravel 5.4 Хранение
Я использую фасад хранилища для хранения аватара, который отлично работает, но я хочу изменить размер изображения, как в предыдущих версиях 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).
Ответы
Ответ 1
Вы пытаетесь передать неправильный объект putFile. Этот метод ожидает объект File (не изображение).
$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;
Представьте, что вы хотите использовать фасад хранилища:
// does not work - Storage::putFile('public/image', $resize);
// Storage::put($path, $contents, $visibility = null)
Storage::put('public/image/myUniqueFileNameHere.jpg', $resize->__toString());
Ответ 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);
Приведенный выше код изменяет размер загруженного файла на ширину 400 пикселей, сохраняя соотношение сторон. Затем кодируется до jpg со скоростью 80%.
Затем файл сохраняется на общедоступном диске.
Обратите внимание, что вы должны указать имя файла, а не только каталог.
Ответ 3
Я делаю так:
- Изменить размер и сохранить изображение где-нибудь (например, в общей папке).
- Создайте новый файл и передайте его в функции файловой системы Laravel (например, putFileAs).
- Удалить файл временного вмешательства
Примечание. Конечно, вы можете изменить его в соответствии с вашими потребностями.
$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);
Ответ 4
Обязательно добавьте use Illuminate\Http\File;
в начало файла, чтобы это работало, и прочитайте раздел документации Автоматическая потоковая передача.
Предполагается, что вы хотите, чтобы все jpegs
$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);
Вот как я делаю это в своем приложении с комментариями, чтобы помочь
// 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]);
Ответ 5
Я сделал это следующим образом, это просто и без путаницы:
//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);
Ответ 6
Самое чистое решение, которое я смог найти - используя собственный фасад 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);
Ответ 7
Попробуйте обновить расширение GD для текущей версии php.
Если это не помогает, попробуйте сохранить измененное изображение на локальном диске и использовать Storage:: putFile.
Вы можете удалить файл после его загрузки на путь хранения.
Второй параметр для метода putFile - это экземпляр класса Image Intervention. Вы должны передать это как второй параметр методу putFile.
$resize->save($absolutePath . 'small/' . $imageName);
Ответ 8
Невозможно сохранить объект \Intervention\Image\Image непосредственно с файловой системой Laravel 5. Вы можете изменить размер изображения с вашего запроса и сохранить его под одним и тем же путем 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);
Ответ 9
Использование Laravel 5.8
У меня была похожая проблема при попытке прочитать файл изображения с помощью Image
когда этот был сохранен и загружен с помощью Storage
.
Помимо всех ответов, я не был уверен, почему это не сработало.
Исключение, когда 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, он создаст черное изображение