Как загрузить и обрезать изображение в Laravel с помощью imgAreaSelect и библиотеки изображений Intervention
Недавно один из наших читателей попросил написать статью о загрузке и обрезке изображений в Laravel. Раньше я публиковал статью на ту же тему для PHP Upload, Crop and Resize Image in PHP. Но когда дело доходит до Laravel, нам нужно вносить изменения в соответствии со стандартами Laravel. В этой статье мы изучаем, как загружать и обрезать изображения в Laravel.
Для этого урока я собираюсь использовать 2 библиотеки – imgAreaSelect и Intervention Image.
imgAreaSelect – это плагин jQuery, который позволяет обрезать изображения, выбирая прямоугольную область изображения. Это легкий и простой в использовании плагин.
С другой стороны, Intervention Image – это библиотека обработки изображений и управления ими. Эта библиотека помогает нам создавать, редактировать и компоновать изображения на стороне сервера.
В этом уроке я буду использовать imgAreaSelect, чтобы получить координаты обрезанного изображения, и библиотеку изображений Intervention, чтобы фактически обрезать изображение на стороне сервера в соответствии с координатами.
Начиная
Для начала вы должны установить Laravel. Если вы еще не создали его, установите его с помощью команды:
composer create-project --prefer-dist laravel/laravel laravel-dev
Приведенная выше команда настроит для вас проект Laravel под названием laravel-dev.
Затем установите библиотеку изображений Intervention в свой проект Laravel. Выполните приведенную ниже команду из корневого каталога проекта.
composer require intervention/image
После установки библиотеки откройте config/app.php
файл и добавьте в него следующие строки.
Добавьте поставщиков услуг для этого пакета в $providers
массив.
InterventionImageImageServiceProvider::class
Добавьте фасад в $aliases
массив.
'Image' => InterventionImageFacadesImage::class
Наконец, загрузите плагин imgAreaSelect. Из загруженного zip-архива скопируйте изображения, файл CSS, JS и вставьте в общую папку проекта Laravel. По сути, ваша структура должна быть такой, как на скриншоте ниже.
Как использовать imgAreaSelect
Поскольку мы собираемся использовать CSS и JS плагина imgAreaSelect, давайте создадим для него структуру. Создайте resources/views/layouts/app.blade.php
файл и добавьте в него приведенный ниже код.
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
@yield('style')
</head>
<body>
<div id="app">
@yield('content')
</div>
@yield('footer')
</body>
</html>
Этот файл действует как общий файл для всех лезвий. Используя заполнители (@yield
), можно разместить код в файле лезвия в соответствующих местах, например, в верхнем, нижнем колонтитуле и т.д.
Создайте image.blade.php
файл внутри resources/views
каталога. Этот блейд-файл будет иметь следующий код.
image.blade.php
@extends('layouts.app')
@section('style')
<link rel="stylesheet" href="{{ asset('css/imgareaselect.css') }}" />
@endsection
@section('content')
@if(session('success'))
<div class="alert alert-success">{{session('success')}}</div>
@endif
<div class="container mt-5">
<form action="{{ url('image') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputImage">Image:</label>
<input type="file" name="profile_image" id="exampleInputImage" class="image" required>
<input type="hidden" name="x1" value="" />
<input type="hidden" name="y1" value="" />
<input type="hidden" name="w" value="" />
<input type="hidden" name="h" value="" />
</div>
{{ csrf_field() }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div class="row mt-5">
<p><img id="previewimage" style="display:none;"/></p>
@if(session('path'))
<img src="{{ session('path') }}" />
@endif
</div>
</div>
@endsection
@section('footer')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="{{ asset('js/jquery.imgareaselect.min.js') }}"></script>
<script>
jQuery(function($) {
var p = $("#previewimage");
$("body").on("change", ".image", function(){
var imageReader = new FileReader();
imageReader.readAsDataURL(document.querySelector(".image").files[0]);
imageReader.onload = function (oFREvent) {
p.attr('src', oFREvent.target.result).fadeIn();
};
});
$('#previewimage').imgAreaSelect({
onSelectEnd: function (img, selection) {
$('input[name="x1"]').val(selection.x1);
$('input[name="y1"]').val(selection.y1);
$('input[name="w"]').val(selection.width);
$('input[name="h"]').val(selection.height);
}
});
});
</script>
@endsection
Вы, возможно, заметили некоторые вещи из указанного выше файла, как @extends('layouts.app')
, @section('style')
, @section('content')
и т.д. Эти участки будут идти в соответствующих местах app.blade.php
. Пользователь может лучше понять это, когда вы просмотрите исходный код этой страницы в браузере.
Чтобы вызвать это представление, создайте контроллер с помощью команды:
php artisan make:controller ImageController --resource
Добавьте ссылку на этот контроллер в файл маршрута.
маршруты / web.php
Route::resource('image', 'ImageController');
Откройте ImageController в редакторе и методом index вызовите файл представления.
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use Image;
class ImageController extends Controller
{
/**
* Display a listing of the resource.
*
* @return IlluminateHttpResponse
*/
public function index()
{
return view('image');
}
.....
}
Запустите php artisan serve
команду, и вы сможете увидеть свою форму по указанному ниже URL-адресу.
http://localhost:8000/image
Когда вы загружаете изображение, вы должны увидеть изображение предварительного просмотра под формой. В этом предварительном просмотре вы можете выбрать часть изображения, которую хотите обрезать.
Загрузка и обрезка изображения с помощью библиотеки изображений вмешательства
На этом этапе мы закончили код на стороне клиента, где пользователь может выбрать часть изображения, которую он хочет обрезать. Следующее задание – обрезать изображение и сохранить его на сервере. Для хранения изображения на сервере я буду использовать функцию хранилища Laravel, где мы создаем символическую ссылку на папку «хранилище». Чтобы создать символическую ссылку, выполните команду:
php artisan storage:link
Эта команда создает каталог хранилища в папке общего доступа.
В нашем контроллере мы уже включили фасад, use Image;
так что вы можете использовать библиотеку изображений Intervention для обрезки изображения на стороне сервера. У store()
метода контроллера должен быть код, как показано ниже:
/**
* Store a newly created resource in storage.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function store(Request $request)
{
if($request->hasFile('profile_image')) {
//get filename with extension
$filenamewithextension = $request->file('profile_image')->getClientOriginalName();
//get filename without extension
$filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
//get file extension
$extension = $request->file('profile_image')->getClientOriginalExtension();
//filename to store
$filenametostore = $filename.'_'.time().'.'.$extension;
//Upload File
$request->file('profile_image')->storeAs('public/profile_images', $filenametostore);
if(!file_exists(public_path('storage/profile_images/crop'))) {
mkdir(public_path('storage/profile_images/crop'), 0755);
}
// crop image
$img = Image::make(public_path('storage/profile_images/'.$filenametostore));
$croppath = public_path('storage/profile_images/crop/'.$filenametostore);
$img->crop($request->input('w'), $request->input('h'), $request->input('x1'), $request->input('y1'));
$img->save($croppath);
// you can save crop image path below in database
$path = asset('storage/profile_images/crop/'.$filenametostore);
return redirect('image')->with(['success' => "Image cropped successfully.", 'path' => $path]);
}
}
В этом коде мы сохраняем обрезанную версию изображения в каталоге public / storage / profile_images / crop. После сохранения мы передаем путь обрезанного изображения обратно в представление. А в файл представления мы уже добавили код, который отображает обрезанное изображение для конечного пользователя.
Установить максимальную ширину изображения
Иногда пользователи могут захотеть определить максимальную ширину для обрезанной версии изображения. Плагин imgAreaSelect предоставляет несколько параметров, таких как aspectRatio, maxWidth, maxHeight и т.д., Для настройки конечного результата изображения. Пользователь может использовать параметр maxWidth, изменив код JavaScript следующим образом:
$('#previewimage').imgAreaSelect({
maxWidth: '1000', // this value is in pixels
onSelectEnd: function (img, selection) {
$('input[name="x1"]').val(selection.x1);
$('input[name="y1"]').val(selection.y1);
$('input[name="w"]').val(selection.width);
$('input[name="h"]').val(selection.height);
}
});
Все дело в том, как загружать и обрезать изображения в Laravel. Надеюсь, вы узнали, как справиться с задачей обрезки изображений. Я хотел бы услышать ваши мысли и предложения в разделе комментариев ниже.
Статьи по Теме
- Изменить размер изображения в Laravel с помощью библиотеки изображений вмешательства
- Руководство по загрузке и сжатию изображений в Laravel
- Создание эскиза в Laravel с помощью библиотеки изображений вмешательства