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, ]; } }