Image Watermark in Laravel 8

Image Watermark in Laravel 8

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.

Image Watermark in Laravel 8

Adapun hasilnya akan terlihat seperti berikut

Image Watermark in Laravel 8

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.

Category:
Share:

Comments