Pendahuluan
Watermark menjadi salah satu cara untuk mengantisipasi penggunaan gambar tanpa izin pemiliknya dimana hak atas gambar tersebut harus mendapatkan izin yang bersangkutan. Ada beragam kasus yang sering menggunakan image protection, misalnya saja foto produk barang yang banyak bertebaran dipasaran, sehingga para seller biasanya menggunakan gambar produk orang lain yang sejenis karena belum memiliki fasilitas dalam menyediakan foto produk sendiri yang berkualitas.
Beruntungnya, salah satu package, yakni Image Intevention menyediakan fitur untuk menyisipkan text ke dalam gambar. Sehingga pada materi kali ini, kita akan menerapkan atau membuat fitur image watermark menggunakan image intervention di Laravel 8. Ide yang akan kita terapkan adalah sebuah fitur manajemen produk dimana kita akan menyimpan informasi terkait nama produk, nama file gambar original dan nama file gambar yang sudah disisipkan text ke dalamnya.
Adapun file gambarnya akan kita simpan ke dalam direktori project Laravelnya itu sendiri.
Baca Juga: CRUD Laravel 8 Dan InertiaJS
Install Laravel 8 & Konfigurasi
Tahap pertama, install Laravel 8 dengan command
composer create-project laravel/laravel watermark-laravel
Buka folder project yang baru saja kita install via command line, dan install package image intevention
composer require intervention/image
Langkah berikutnya adalah membuat table untuk menyimpan informasi terkait produk, generate model dan migrationnya menggunakan command
php artisan make:model Product -m
Kemudian buka file migration yang baru saja kita buat dan modifikasi menjadi
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('original_image');
$table->string('image');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
Langkah berikutnya ada buka file .env
dan sesuaikan informasi database Anda. Jika sudah selesai, maka jalankan command php artisan migrate
untuk mengeksekusi migration yang kita miliki.
Fitur Image Watermark
Tibalah saatnya untuk menyediakan fitur untuk menampilkan data product dan fitur untuk upload gambar beserta informasi product sekaligus men-generate watermark-nya. Buat controller dengan command
php artisan make:controller ProductController
Buka file ProductController.php
dan modifikasi menjadi
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
use Illuminate\Support\Str;
use Image;
class ProductController extends Controller
{
public function index()
{
$products = Product::orderBy('created_at', 'DESC')->paginate(10);
return view('product', compact('products'));
}
}
Buat file product.blade.php
di dalam folder resources/views
dan tambahkan code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Watermark Image Laravel</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row mt-5">
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h4 class="card-title">Tambah Produk</h4>
</div>
<div class="card-body">
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if (session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
<form action="{{ route('product.store') }}" method="post" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="">Nama Produk</label>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group mt-2">
<label for="">Gambar</label>
<input type="file" name="image" id="image">
</div>
<div class="form-group mt-2">
<button class="btn btn-primary btn-sm">Upload</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">Manajemen Produk</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-bordered table-stripped">
<thead class="thead-dark">
<tr>
<th>Nama Produk</th>
<th>Gambar</th>
<th>Gambar Watermark</th>
</tr>
</thead>
<tbody>
@forelse($products as $row)
<tr>
<td>{{ $row->name }}</td>
<td><a href="{{ asset('storage/products/' . $row->original_image) }}" target="_blank">Show Image</a></td>
<td><a href="{{ asset('storage/products/' . $row->image) }}" target="_blank">Show Image</a></td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center">Tidak ada data</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Buka file routes/web.php
untuk mendefinisikan routing-nya
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', [ProductController::class, 'index']);
Route::post('/', [ProductController::class, 'store'])->name('product.store');
Nah, hal yang menarik adalah pada bagian mengolah data yang dikirimkan setelah form di-submit. Buka file ProductController.php
dan tambahkan method store()
public function store(Request $request)
{
//VALIDASI DATA YANG DITERIMA
$this->validate($request, [
'name' => 'required|string|max:80',
'image' => 'required|image|mimes:jpg,jpeg,png'
]);
//JIKA FILE GAMBARNYA ADA
if ($request->hasFile('image')) {
$file = $request->file('image'); //GET FILE GAMBARNYA
$filenameWithoutEx = Str::slug($request->name) . '-' . time(); //GENERATE NAMA FILE TANPA EXTENSION
$filename = $filenameWithoutEx . '.' . $file->getClientOriginalExtension(); //GENERATE NAMA FILE DENGAN EXTENSION
$file->storeAs('public/products', $filename); //SIMPAN FILE ORIGINAL YANG BELUM BERISI WATERMARK KE DALAM STORAGE/APP/PUBLIC/PRODUCTS
$img = Image::make(storage_path('app/public/products/' . $filename)); //GET FILE YANG SUDAH DISIMPAN
//KEMUDIAN KITA SISIPKAN WATERMARK DENGAN TEXT DAENGWEB.ID
//X = 200, Y = 150. SILAHKAN DISESUAIKAN UNTUK POSISINYA
$img->text('DaengWeb.id', 200, 150, function($font) {
$font->file(public_path('milkyroad.ttf')); //LOAD FONT-NYA JIKA ADA, SILAHKAN DOWNLOAD SENDIRI
$font->size(50);
$font->color('#e74c3c');
$font->align('center');
$font->valign('middle');
$font->angle(30);
});
$filenameWatermark = $filenameWithoutEx . '_watermark.' . $file->getClientOriginalExtension(); //GENERATE NAMA FILE YANG SUDAH BERISI WATERMARK
$img->save(storage_path('app/public/products/' . $filenameWatermark)); //DAN SIMPAN JUGA KE DALAM FOLDER YG SAMA
//SIMPAN INFORMASI PRODUKNYA KE DALAM TABLE PRODUCTS
Product::create([
'name' => $request->name,
'original_image' => $filename,
'image' => $filenameWatermark
]);
return redirect()->back()->with(['success' => 'Produk Berhasil Di Unggah']);
}
return redirect()->back()->with(['error' => 'File Gambar Tidak Ditemukan']);
}
Jangan lupa untuk menjalankan command php artisan storage:link
agar file storage bisa diakses secara publik.
Adapun hasilnya akan terlihat seperti berikut
Baca Juga: Drag & Drop Upload File Dropzone di Laravel 8
Kesimpulan
Image Intervention adalah sebuah library untuk memanipulasi gambar. Ada banyak fitur yang bisa kamu kombinasikan agar watermark-nya terlihat lebih menarik. Sebab dalam materi ini, kita hanya belajar bagaimana membuat watermark, sedangkan style-nya kembali ke selera para pembaca.
Adapun dokumentasi code dari materi ini bisa dilihat di Github.
Comments