Compare commits

...

3 Commits

Author SHA1 Message Date
Daeng Deni Mardaeni
f402c0831a 🚀 feat(preview-laporan): Optimasi tampilan gambar dengan resize otomatis dan peningkatan DPI PDF
Perubahan pada PreviewLaporanService:
- Menambahkan set_option('dpi', '96') untuk meningkatkan kualitas render PDF

Perubahan pada foto-jaminan blade template:
- Implementasi helper function `resize_image()` untuk resize gambar jaminan
- Mengubah gambar asli menjadi versi yang sudah di-resize (800x400px, quality 25%)
- Mengoptimalkan ukuran file gambar untuk preview laporan
- Menjaga aspect ratio gambar tetap proporsional
- Meningkatkan performa loading gambar di PDF preview

Optimasi ini bertujuan untuk:
- Mengurangi ukuran file PDF hasil preview
- Meningkatkan kecepatan loading gambar
- Menjaga kualitas visual yang tetap baik
- Mengurangi memory usage saat generate PDF
2025-12-24 11:15:39 +07:00
Daeng Deni Mardaeni
ceca0aa5e8 feat(helper): Tambahkan helper function resize_image untuk integrasi ImageResizeService
Menambahkan helper function `resize_image()` di app/Helpers/Lpj.php untuk:
- Menyediakan interface yang lebih mudah digunakan untuk resize gambar
- Menerima parameter: path gambar, width, height (opsional), dan quality
- Menggunakan ImageResizeService untuk proses resize yang sudah ada
- Memudahkan developer untuk resize gambar secara on-the-fly
- Mengembalikan path gambar yang sudah di-resize

Function ini mengabstraksi ImageResizeService agar bisa dipanggil dengan
lebih sederhana tanpa perlu dependency injection manual.
2025-12-24 11:14:35 +07:00
Daeng Deni Mardaeni
43361f81e7 🎨 feat(ImageResizeService): Tambahkan service resize gambar dengan fitur kualitas dan aspect ratio
Menambahkan ImageResizeService untuk mengelola proses resize gambar dengan fitur:
- Resize gambar dengan menjaga aspect ratio atau force resize
- Support resize berdasarkan width saja, height saja, atau keduanya
- Kustomisasi kualitas kompresi gambar (default 80%)
- Penyimpanan hasil resize di folder terpisah ('resized')
- Nama file yang deskriptif dengan format: {filename}_{width}x{height}_{quality}.{extension}
- Error handling dengan fallback ke gambar original
- Logging untuk monitoring proses resize

Service ini menggunakan Intervention Image Laravel untuk manipulasi gambar dan
Laravel Storage untuk manajemen file. Cocok untuk optimasi gambar di aplikasi
LPJ module.
2025-12-24 11:13:28 +07:00
4 changed files with 103 additions and 5 deletions

View File

@@ -20,6 +20,7 @@
use Modules\Usermanagement\Models\User;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Modules\Lpj\Services\ImageResizeService;
/**
* Format tanggal ke dalam format Bahasa Indonesia
@@ -775,3 +776,20 @@
Log::error('Tidak dapat memparsing timestamp dengan format apapun: "' . $timestamp . '"');
return null;
}
if (!function_exists('resize_image')) {
/**
* Merubah ukuran gambar secara on-the-fly dan mengembalikan path-nya.
*
* @param string $path Path asli gambar.
* @param int|null $width Lebar yang diinginkan.
* @param int|null $height Tinggi yang diinginkan (opsional, akan menjaga rasio aspek jika null).
* @param int $quality Kualitas gambar (1-100).
* @return string Path gambar yang sudah di-resize.
*/
function resize_image(string $path, ?int $width, ?int $height = null, int $quality = 80): string
{
return app(ImageResizeService::class)->resize($path, $width, $height, $quality);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Modules\Lpj\Services;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Laravel\Facades\Image;
class ImageResizeService
{
/**
* Resize an image and store it.
*
* @param string $originalPath
* @param int $width
* @param int|null $height
* @param int $quality
* @return string
*/
public function resize(string $originalPath, ?int $width, ?int $height = null, int $quality = 80): string
{
if (empty($originalPath) || !Storage::disk('public')->exists($originalPath)) {
Log::warning("Image Service: Original path is empty or does not exist: {$originalPath}");
return '';
}
$height = null;
$pathinfo = pathinfo($originalPath);
// Kembali menggunakan direktori 'resized' dan menyertakan dimensi di nama file
$resizedPath = "{$pathinfo['dirname']}/resized/{$pathinfo['filename']}_{$width}x{$height}_{$quality}.{$pathinfo['extension']}";
if (Storage::disk('public')->exists($resizedPath)) {
return $resizedPath;
}
try {
$originalFullPath = Storage::disk('public')->path($originalPath);
$newFullPath = Storage::disk('public')->path($resizedPath);
$image = Image::read($originalFullPath);
// Resize dengan menjaga aspek rasio jika height null
if ($width && $height) {
// Paksa resize ke dimensi yang ditentukan, abaikan aspek rasio
$image->resize($width, $height);
} elseif ($width && !$height) {
// Resize hanya berdasarkan width, tinggi menyesuaikan aspek rasio
$image->scale(width: $width);
} elseif (!$width && $height) {
// Resize hanya berdasarkan height, lebar menyesuaikan aspek rasio
$image->scale(height: $height);
}
if (!Storage::disk('public')->exists(dirname($resizedPath))) {
Storage::disk('public')->makeDirectory(dirname($resizedPath));
}
// Simpan dengan kualitas yang ditentukan
$image->save($newFullPath, $quality);
Log::info("Image Service: Successfully resized {$originalPath} to {$resizedPath} with quality {$quality}%.");
return $resizedPath;
} catch (\Exception $e) {
Log::error("Image Service: Resize failed for {$originalPath}. Error: " . $e->getMessage());
return $originalPath; // Fallback ke gambar asli jika gagal
}
}
}

View File

@@ -347,6 +347,7 @@ class PreviewLaporanService
$pdf->setPaper('A4', 'portrait');
$pdf->set_option('isHtml5ParserEnabled', true);
$pdf->set_option('isPhpEnabled', true);
$pdf->set_option('dpi', '96');
return $pdf;
}

View File

@@ -154,10 +154,12 @@
? $fallbackPath
: $originalPath;
$resizedPath = resize_image($pathToUse, 800, 400, 25);
$filePath =
$statusLpj == 1
? storage_path('app/public/' . $pathToUse)
: asset('storage/' . $pathToUse);
? storage_path('app/public/' . $resizedPath)
: asset('storage/' . $resizedPath);
$extension = strtolower(pathinfo($pathToUse, PATHINFO_EXTENSION));
$isImage = in_array($extension, [
@@ -248,12 +250,16 @@
style="align-content: center; text-align: center; margin-bottom: 20px">
@foreach ($chunkedPhotos as $item)
@php
$originalPath = $item['path'];
$resizedPath = resize_image($originalPath, 800, 400, 25);
$filePath =
$statusLpj == 1
? storage_path('app/public/' . $item['path'])
: asset('storage/' . $item['path']);
? storage_path('app/public/' . $resizedPath)
: asset('storage/' . $resizedPath);
$extension = strtolower(pathinfo($item['path'], PATHINFO_EXTENSION));
$extension = strtolower(pathinfo($originalPath, PATHINFO_EXTENSION));
$isImage = in_array($extension, [
'jpg',
'jpeg',