Como fazer upload e recortar imagens no Laravel usando imgAreaSelect e a biblioteca de imagens de intervenção
Recentemente, um de nossos leitores pediu para escrever um artigo sobre upload e recorte de imagens no Laravel. No passado, publiquei o artigo sobre o mesmo tópico para PHP Upload, Crop and Resize Image in PHP. Mas quando se trata do Laravel, precisamos fazer modificações de acordo com os padrões do Laravel. Neste artigo, estudamos como fazer upload e recortar imagens no Laravel.
Para este tutorial, vou usar 2 bibliotecas – imgAreaSelect e Intervention Image.
imgAreaSelect é um plugin jQuery que permite cortar imagens selecionando uma área retangular de uma imagem. É um plugin leve e fácil de usar.
Por outro lado, Intervention Image é uma biblioteca de tratamento e manipulação de imagens. Esta biblioteca nos ajuda a criar, editar e compor imagens no lado do servidor.
Neste tutorial, usarei imgAreaSelect para obter as coordenadas da imagem cortada e a biblioteca de imagens de intervenção para realmente cortar a imagem no lado do servidor de acordo com as coordenadas.
Começando
Para começar, você deve ter instalado o Laravel. Se você ainda não o criou, instale-o por meio do comando:
composer create-project --prefer-dist laravel/laravel laravel-dev
O comando acima irá configurar o projeto Laravel chamado ‘laravel-dev’ para você.
A seguir, instale a biblioteca de imagens Intervention em seu projeto Laravel. Execute o comando abaixo a partir do diretório raiz do projeto.
composer require intervention/image
Depois de instalar a biblioteca, abra o config/app.php
arquivo e adicione as seguintes linhas a ele.
Adicione os provedores de serviço para este pacote na $providers
matriz.
InterventionImageImageServiceProvider::class
Adicione a fachada ao $aliases
array.
'Image' => InterventionImageFacadesImage::class
Finalmente, baixe o plugin imgAreaSelect. Do zip baixado, copie as imagens, CSS, arquivo JS e cole na pasta pública do projeto Laravel. Basicamente, sua estrutura deve ser como a imagem abaixo.
Como usar imgAreaSelect
Como vamos usar CSS e JS do plugin imgAreaSelect, vamos construir uma estrutura para ele. Crie um resources/views/layouts/app.blade.php
arquivo e adicione o código abaixo nele.
<!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>
Este arquivo atua como um arquivo comum para todos os blades. Usando os marcadores de posição (@yield
), pode-se colocar o código no arquivo blade nos respectivos locais, como no cabeçalho, rodapé, etc.
Crie um image.blade.php
arquivo dentro do resources/views
diretório. Este arquivo blade terá o seguinte código.
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
Você deve ter notado algumas coisas a partir do arquivo acima como @extends('layouts.app')
, @section('style')
, @section('content')
, etc. Estas seções vão nos respectivos locais de app.blade.php
. O usuário pode ter uma ideia melhor disso ao visualizar o código-fonte desta página no navegador.
Para chamar essa visualização, crie um controlador usando o comando:
php artisan make:controller ImageController --resource
Adicione a referência deste controlador no arquivo de rota.
rotas / web.php
Route::resource('image', 'ImageController');
Abra o ‘ImageController’ no editor e para o método ‘index’ chame o arquivo de visualização.
<?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');
}
.....
}
Execute o php artisan serve
comando e você poderá ver seu formulário no URL abaixo.
http://localhost:8000/image
Ao carregar a imagem, você deverá ver a imagem de visualização abaixo do formulário. Nessa visualização, você pode selecionar uma parte da imagem que deseja cortar.
Carregar e cortar imagem usando a biblioteca de imagens de intervenção
Neste ponto, concluímos com o código do lado do cliente, onde o usuário pode escolher uma parte da imagem que deseja cortar. O próximo trabalho é cortar a imagem e armazená-la no servidor. Para armazenar uma imagem em um servidor, usarei o recurso de armazenamento do Laravel, onde criamos um link simbólico de uma pasta de ‘armazenamento’. Para criar um link simbólico, execute o comando:
php artisan storage:link
Este comando cria um diretório de ‘armazenamento’ na pasta ‘pública’.
Em nosso controlador, já incluímos uma fachada, use Image;
então você está pronto para usar a biblioteca de imagens de intervenção para cortar a imagem no lado do servidor. O store()
método do controlador deve ter o código abaixo:
/**
* 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]);
}
}
Neste código, estamos armazenando uma versão recortada de uma imagem no diretório ‘public / storage / profile_images / crop’. Depois de armazená-lo, estamos passando um caminho da imagem recortada de volta à vista. E no arquivo de visualização, já adicionamos um código que exibe a imagem cortada para o usuário final.
Definir a largura máxima da imagem
Às vezes, os usuários podem querer definir a largura máxima para a versão de recorte de uma imagem. O plugin imgAreaSelect fornece várias opções como aspectRatio, maxWidth, maxHeight, etc. para personalizar o resultado final de uma imagem. Um usuário pode usar a opção maxWidth alterando o código JavaScript da seguinte maneira:
$('#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);
}
});
É tudo sobre como fazer upload e cortar imagens no Laravel. Espero que você saiba como lidar com a tarefa de recortar imagens. Eu gostaria de ouvir seus pensamentos e sugestões na seção de comentários abaixo.
Artigos relacionados
- Redimensionar imagem no Laravel usando a biblioteca de imagens de intervenção
- Um guia para fazer upload e compactar imagens no Laravel
- Crie uma miniatura no Laravel usando a biblioteca de imagens de intervenção