10-04-2026

This commit is contained in:
Kevin Adametz 2026-04-10 17:18:17 +02:00
parent 4d6b4930b2
commit 4bb89aad8c
836 changed files with 52961 additions and 5950 deletions

View file

@ -0,0 +1,124 @@
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class ConvertImagesToWebP extends Command
{
protected $signature = 'images:convert-webp
{--path=img/assets : Relative path inside public/}
{--quality=85 : WebP quality (1-100)}
{--force : Overwrite existing WebP files}
{--dry-run : Show what would be converted without doing it}';
protected $description = 'Convert JPG/JPEG/PNG images to WebP format using GD';
public function handle(): int
{
$relativePath = $this->option('path');
$quality = (int) $this->option('quality');
$force = (bool) $this->option('force');
$dryRun = (bool) $this->option('dry-run');
$basePath = public_path($relativePath);
if (! File::isDirectory($basePath)) {
$this->error("Directory not found: {$basePath}");
return self::FAILURE;
}
$extensions = ['jpg', 'jpeg', 'png'];
$files = collect(File::allFiles($basePath))
->filter(fn ($file) => in_array(strtolower($file->getExtension()), $extensions));
if ($files->isEmpty()) {
$this->info('No images found to convert.');
return self::SUCCESS;
}
$this->info(sprintf('Found %d images in %s', $files->count(), $relativePath));
$converted = 0;
$skipped = 0;
$savedBytes = 0;
foreach ($files as $file) {
$webpPath = preg_replace('/\.(jpe?g|png)$/i', '.webp', $file->getPathname());
if (File::exists($webpPath) && ! $force) {
$skipped++;
continue;
}
if ($dryRun) {
$this->line(" Would convert: {$file->getRelativePathname()}");
$converted++;
continue;
}
$result = $this->convertToWebP($file->getPathname(), $webpPath, $quality);
if ($result) {
$originalSize = $file->getSize();
$webpSize = filesize($webpPath);
$saving = $originalSize - $webpSize;
$savedBytes += $saving;
$percent = $originalSize > 0 ? round(($saving / $originalSize) * 100, 1) : 0;
$this->line(sprintf(
' <info>✓</info> %s → %s KB → %s KB (<comment>-%s%%</comment>)',
$file->getRelativePathname(),
round($originalSize / 1024, 1),
round($webpSize / 1024, 1),
$percent
));
$converted++;
} else {
$this->warn(" ✗ Failed: {$file->getRelativePathname()}");
}
}
$this->newLine();
$this->info(sprintf(
'Done: %d converted, %d skipped, %.1f KB saved',
$converted,
$skipped,
$savedBytes / 1024
));
return self::SUCCESS;
}
private function convertToWebP(string $sourcePath, string $destPath, int $quality): bool
{
$extension = strtolower(pathinfo($sourcePath, PATHINFO_EXTENSION));
$image = match ($extension) {
'jpg', 'jpeg' => @imagecreatefromjpeg($sourcePath),
'png' => @imagecreatefrompng($sourcePath),
default => false,
};
if ($image === false) {
return false;
}
if ($extension === 'png') {
imagepalettetotruecolor($image);
imagealphablending($image, true);
imagesavealpha($image, true);
}
$result = imagewebp($image, $destPath, $quality);
imagedestroy($image);
return $result;
}
}