disk); $path = $media->getPathRelativeToRoot(); if (! $disk->exists($path)) { return null; } $mime = $media->mime_type ?: 'application/octet-stream'; return 'data:'.$mime.';base64,'.base64_encode($disk->get($path)); } public static function fromPath(?string $absolutePath, int $maxWidth = 80, int $maxHeight = 80): ?string { if (! $absolutePath || ! file_exists($absolutePath)) { return null; } $contents = file_get_contents($absolutePath); if ($contents === false) { return null; } return self::encodeResizedImage($contents, $maxWidth, $maxHeight) ?? self::encodeRawFile($absolutePath, $contents); } public static function thumbnailForPdf(?Media $media, int $maxWidth = 150, int $maxHeight = 80): ?string { if (! $media) { return null; } $disk = Storage::disk($media->disk); $path = $media->getPathRelativeToRoot(); if (! $disk->exists($path)) { return null; } $mime = $media->mime_type ?? ''; if (! str_starts_with($mime, 'image/')) { return null; } $contents = $disk->get($path); return self::encodeResizedImage($contents, $maxWidth, $maxHeight) ?? self::fromMedia($media); } private static function encodeResizedImage(string $contents, int $maxWidth, int $maxHeight): ?string { if (! extension_loaded('gd')) { return null; } $image = @imagecreatefromstring($contents); if ($image === false) { return null; } $width = imagesx($image); $height = imagesy($image); $ratio = min($maxWidth / $width, $maxHeight / $height, 1); $newWidth = max(1, (int) round($width * $ratio)); $newHeight = max(1, (int) round($height * $ratio)); $thumb = imagecreatetruecolor($newWidth, $newHeight); if ($thumb === false) { imagedestroy($image); return null; } imagecopyresampled($thumb, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); imagedestroy($image); ob_start(); imagejpeg($thumb, quality: 75); imagedestroy($thumb); $jpeg = ob_get_clean(); if ($jpeg === false || $jpeg === '') { return null; } return 'data:image/jpeg;base64,'.base64_encode($jpeg); } private static function encodeRawFile(string $absolutePath, string $contents): ?string { $extension = strtolower(pathinfo($absolutePath, PATHINFO_EXTENSION)); $mime = match ($extension) { 'png' => 'image/png', 'jpg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'webp' => 'image/webp', default => null, }; if ($mime === null) { return null; } return 'data:'.$mime.';base64,'.base64_encode($contents); } }