Jak przesłać i przyciąć obraz w Laravel za pomocą imgAreaSelect i biblioteki obrazów interwencyjnych
Ostatnio jeden z naszych czytelników poprosił o napisanie artykułu na temat przesyłania i przycinania zdjęć w Laravelu. W przeszłości publikowałem artykuł na ten sam temat dla PHP Upload, Crop and Resize Image in PHP. Ale jeśli chodzi o Laravela, musimy dokonać modyfikacji zgodnie ze standardami Laravela. W tym artykule dowiemy się, jak przesyłać i przycinać obrazy w Laravel.
W tym samouczku użyję 2 bibliotek – imgAreaSelect i Intervention Image.
imgAreaSelect to wtyczka jQuery, która umożliwia przycinanie obrazów poprzez wybranie prostokątnego obszaru obrazu. Jest to lekka wtyczka i łatwa w użyciu.
Z drugiej strony, Intervention Image to biblioteka do obsługi i manipulacji obrazami. Ta biblioteka pomaga nam tworzyć, edytować i komponować obrazy po stronie serwera.
W tym samouczku użyję imgAreaSelect, aby uzyskać współrzędne przyciętego obrazu i biblioteki obrazów Interwencji, aby faktycznie przyciąć obraz po stronie serwera zgodnie ze współrzędnymi.
Pierwsze kroki
Na początek powinieneś mieć zainstalowany Laravel. Jeśli jeszcze nie utworzyłeś, zainstaluj go za pomocą polecenia:
composer create-project --prefer-dist laravel/laravel laravel-dev
Powyższe polecenie skonfiguruje dla ciebie projekt Laravel o nazwie ‘laravel-dev’.
Następnie zainstaluj bibliotekę obrazów Interwencja w swoim projekcie Laravel. Uruchom poniższe polecenie z katalogu głównego projektu.
composer require intervention/image
Po zainstalowaniu biblioteki otwórz config/app.php
plik i dodaj do niego następujące wiersze.
Dodaj dostawców usług dla tego pakietu w $providers
tablicy.
InterventionImageImageServiceProvider::class
Dodaj fasadę do $aliases
szyku.
'Image' => InterventionImageFacadesImage::class
Na koniec pobierz wtyczkę imgAreaSelect. Z pobranego pliku zip skopiuj obrazy, CSS, plik JS i wklej do publicznego folderu projektu Laravel. Zasadniczo twoja struktura powinna wyglądać jak na poniższym zrzucie ekranu.
Jak korzystać z imgAreaSelect
Ponieważ zamierzamy korzystać z CSS i JS wtyczki imgAreaSelect, zbudujmy dla niego strukturę. Utwórz resources/views/layouts/app.blade.php
plik i dodaj do niego poniższy kod.
<!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>
Ten pilnik działa jak wspólny pilnik dla wszystkich ostrzy. Za pomocą symboli zastępczych (@yield
) można umieścić kod w pliku blade w odpowiednich miejscach, np. w nagłówku, stopce itp.
Utwórz image.blade.php
plik w resources/views
katalogu. Ten plik ostrza będzie miał następujący kod.
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
Można zauważyć pewne rzeczy z powyższego pliku jak @extends('layouts.app')
, @section('style')
, @section('content')
, itd. Te sekcje pójdzie w odpowiednich miejscach app.blade.php
. Użytkownik może się o tym lepiej zorientować, wyświetlając źródło tej strony w przeglądarce.
Aby wywołać ten widok, utwórz kontroler za pomocą polecenia:
php artisan make:controller ImageController --resource
Dodaj odwołanie do tego kontrolera w pliku trasy.
trasy/web.php
Route::resource('image', 'ImageController');
Otwórz ‘ImageController’ w edytorze i metodą ‘index’ wywołaj plik widoku.
<?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');
}
.....
}
Uruchom php artisan serve
polecenie, a będziesz mógł zobaczyć swój formularz pod poniższym adresem URL.
http://localhost:8000/image
Po przesłaniu obrazu powinieneś zobaczyć obraz podglądu pod formularzem. Z tego podglądu możesz wybrać część obrazu, którą chcesz przyciąć.
Prześlij i przytnij obraz za pomocą biblioteki obrazów interwencyjnych
W tym momencie kończymy kod po stronie klienta, w którym użytkownik może wybrać część obrazu, który chce przyciąć. Następnym zadaniem jest przycięcie obrazu i zapisanie go na serwerze. Do przechowywania obrazu na serwerze użyję funkcji przechowywania Laravel, gdzie tworzymy dowiązanie symboliczne folderu ‘storage’. Aby utworzyć dowiązanie symboliczne, uruchom polecenie:
php artisan storage:link
To polecenie tworzy katalog „storage" w folderze „public”.
W naszym kontrolerze zawarliśmy już fasadę, use Image;
więc dobrze jest skorzystać z biblioteki obrazów Interwencji, aby przyciąć obraz po stronie serwera. Metoda kontrolera store()
powinna mieć kod jak poniżej:
/**
* 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]);
}
}
W tym kodzie przechowujemy przyciętą wersję obrazu w katalogu „public/storage/profile_images/crop”. Po jego zapisaniu przekazujemy ścieżkę wykadrowanego obrazu z powrotem do widoku. W pliku widoku dodaliśmy już kod, który wyświetla przycięty obraz użytkownikowi końcowemu.
Ustaw maksymalną szerokość obrazu
Czasami użytkownicy mogą chcieć zdefiniować maksymalną szerokość przyciętej wersji obrazu. Wtyczka imgAreaSelect udostępnia kilka opcji, takich jak proporcje, maxWidth, maxHeight itp., aby dostosować końcowy wynik obrazu. Użytkownik może użyć opcji maxWidth zmieniając kod JavaScript w następujący sposób:
$('#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);
}
});
Chodzi o to, jak przesyłać i przycinać obrazy w Laravel. Mam nadzieję, że wiesz, jak poradzić sobie z przycinaniem obrazów. Chciałbym usłyszeć wasze przemyślenia i sugestie w sekcji komentarzy poniżej.
Powiązane artykuły
- Zmień rozmiar obrazu w Laravel za pomocą biblioteki obrazów interwencyjnych
- Przewodnik po przesyłaniu i kompresowaniu obrazów w Laravel
- Utwórz miniaturę w Laravel za pomocą biblioteki obrazów interwencyjnych