feat: add automated WebP conversion and resizing for hero background images
This commit is contained in:
+103
-5
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user