feat: add automated WebP conversion and resizing for hero background images

This commit is contained in:
Ümit Tunç
2026-06-02 06:44:57 +03:00
parent 9c4dc0ff11
commit d245055bf4
+103 -5
View File
@@ -75,17 +75,115 @@ class Setting extends Model
$this->attributes['value'] = $value ? '1' : '0';
}
/**
* Set value from different field names
*/
public function setValueFileAttribute($value)
{
// Filament bazen dosya yolunu array olarak döndürebilir, bu durumda ilk elemanı alıyoruz
if (is_array($value)) {
$this->attributes['value'] = array_values($value)[0] ?? null;
$filePath = array_values($value)[0] ?? null;
} else {
$this->attributes['value'] = $value;
$filePath = $value;
}
if ($filePath && $this->key === 'hero_bg') {
$filePath = $this->processHeroBackground($filePath);
}
$this->attributes['value'] = $filePath;
}
/**
* Process the hero background image: convert to webp, resize if necessary, and compress.
*/
protected function processHeroBackground($filePath)
{
try {
$disk = \Illuminate\Support\Facades\Storage::disk('public');
if (!$disk->exists($filePath)) {
return $filePath;
}
$absolutePath = $disk->path($filePath);
// Get image info
$imageInfo = @getimagesize($absolutePath);
if (!$imageInfo) {
return $filePath;
}
$mimeType = $imageInfo['mime'];
// Create GD image resource based on mime type
switch ($mimeType) {
case 'image/jpeg':
case 'image/jpg':
$image = @imagecreatefromjpeg($absolutePath);
break;
case 'image/png':
$image = @imagecreatefrompng($absolutePath);
break;
case 'image/webp':
$image = @imagecreatefromwebp($absolutePath);
break;
case 'image/gif':
$image = @imagecreatefromgif($absolutePath);
break;
default:
return $filePath;
}
if (!$image) {
return $filePath;
}
// Preserve transparency or handle it for webp if needed
imagealphablending($image, true);
imagesavealpha($image, true);
$originalWidth = imagesx($image);
$originalHeight = imagesy($image);
// Target dimensions: Hero bg size, max width 1920px
$maxWidth = 1920;
if ($originalWidth > $maxWidth) {
$newWidth = $maxWidth;
$newHeight = (int) (($originalHeight / $originalWidth) * $maxWidth);
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
// Preserve transparency
imagealphablending($resizedImage, false);
imagesavealpha($resizedImage, true);
// Resize
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $originalWidth, $originalHeight);
imagedestroy($image);
$image = $resizedImage;
}
// Generate new webp path
$pathInfo = pathinfo($filePath);
$newWebpPath = $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '.webp';
$absoluteWebpPath = $disk->path($newWebpPath);
// Save as webp with 80% quality (excellent quality-to-size ratio)
if (imagewebp($image, $absoluteWebpPath, 80)) {
imagedestroy($image);
// If the file extension changed, delete the original file
if ($newWebpPath !== $filePath) {
$disk->delete($filePath);
}
return $newWebpPath;
}
imagedestroy($image);
} catch (\Exception $e) {
// Log error or fallback to original
\Illuminate\Support\Facades\Log::error('Hero background image processing failed: ' . $e->getMessage());
}
return $filePath;
}
/**