simedkom/app/Filament/Support/MediaDataUri.php

128 lines
3.3 KiB
PHP

<?php
namespace App\Filament\Support;
use Illuminate\Support\Facades\Storage;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class MediaDataUri
{
public static function fromMedia(?Media $media): ?string
{
if (! $media) {
return null;
}
$disk = Storage::disk($media->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);
}
}