Files
SkinbaseNova/app/Services/Upload/PreviewService.php
2026-02-14 15:14:12 +01:00

80 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Upload;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManager;
use RuntimeException;
final class PreviewService
{
private ?ImageManager $manager = null;
public function __construct()
{
try {
$this->manager = extension_loaded('gd') ? ImageManager::gd() : ImageManager::imagick();
} catch (\Throwable $e) {
$this->manager = null;
}
}
public function generateFromImage(string $uploadId, string $sourcePath): array
{
if ($this->manager === null) {
throw new RuntimeException('PreviewService requires Intervention Image.');
}
$disk = Storage::disk('local');
if (! $disk->exists($sourcePath)) {
return $this->generatePlaceholder($uploadId);
}
$absolute = $disk->path($sourcePath);
$previewPath = "tmp/drafts/{$uploadId}/preview.webp";
$thumbPath = "tmp/drafts/{$uploadId}/thumb.webp";
$preview = $this->manager->read($absolute)->scaleDown(1280, 1280);
$thumb = $this->manager->read($absolute)->cover(320, 320);
$previewEncoded = (string) $preview->encode(new \Intervention\Image\Encoders\WebpEncoder(85));
$thumbEncoded = (string) $thumb->encode(new \Intervention\Image\Encoders\WebpEncoder(82));
$disk->put($previewPath, $previewEncoded);
$disk->put($thumbPath, $thumbEncoded);
return [
'preview_path' => $previewPath,
'thumb_path' => $thumbPath,
];
}
public function generateFromArchive(string $uploadId, ?string $screenshotPath = null): array
{
if ($screenshotPath !== null && Storage::disk('local')->exists($screenshotPath)) {
return $this->generateFromImage($uploadId, $screenshotPath);
}
return $this->generatePlaceholder($uploadId);
}
public function generatePlaceholder(string $uploadId): array
{
$disk = Storage::disk('local');
$previewPath = "tmp/drafts/{$uploadId}/preview.webp";
$thumbPath = "tmp/drafts/{$uploadId}/thumb.webp";
// 1x1 transparent webp
$tinyWebp = base64_decode('UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAAAfQ//73v/+BiOh/AAA=');
$disk->put($previewPath, $tinyWebp ?: '');
$disk->put($thumbPath, $tinyWebp ?: '');
return [
'preview_path' => $previewPath,
'thumb_path' => $thumbPath,
];
}
}