38438-vm/includes/media_helper.php
2026-02-15 16:33:12 +00:00

108 lines
3.0 KiB
PHP

<?php
declare(strict_types=1);
/**
* Creates a thumbnail for an image.
*
* @param string $sourcePath Path to the source image.
* @param string $targetPath Path where the thumbnail should be saved.
* @param int $maxWidth Maximum width of the thumbnail.
* @param int $maxHeight Maximum height of the thumbnail.
* @return bool True on success, false on failure.
*/
function createThumbnail(string $sourcePath, string $targetPath, int $maxWidth = 400, int $maxHeight = 400): bool {
if (!file_exists($sourcePath)) {
return false;
}
$imageInfo = getimagesize($sourcePath);
if ($imageInfo === false) {
return false;
}
list($width, $height, $type) = $imageInfo;
$sourceImage = null;
switch ($type) {
case IMAGETYPE_JPEG:
$sourceImage = @imagecreatefromjpeg($sourcePath);
break;
case IMAGETYPE_PNG:
$sourceImage = @imagecreatefrompng($sourcePath);
break;
case IMAGETYPE_GIF:
$sourceImage = @imagecreatefromgif($sourcePath);
break;
case IMAGETYPE_WEBP:
$sourceImage = @imagecreatefromwebp($sourcePath);
break;
default:
return false;
}
if (!$sourceImage) {
return false;
}
// Calculate dimensions
$ratio = min($maxWidth / $width, $maxHeight / $height);
if ($ratio >= 1) {
$newWidth = $width;
$newHeight = $height;
} else {
$newWidth = (int)($width * $ratio);
$newHeight = (int)($height * $ratio);
}
$thumbnail = imagecreatetruecolor($newWidth, $newHeight);
// Handle transparency for PNG/GIF/WebP
if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF || $type == IMAGETYPE_WEBP) {
imagealphablending($thumbnail, false);
imagesavealpha($thumbnail, true);
$transparent = imagecolorallocatealpha($thumbnail, 255, 255, 255, 127);
imagefilledrectangle($thumbnail, 0, 0, $newWidth, $newHeight, $transparent);
}
imagecopyresampled($thumbnail, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if (!is_dir(dirname($targetPath))) {
mkdir(dirname($targetPath), 0775, true);
}
$success = false;
switch ($type) {
case IMAGETYPE_JPEG:
$success = imagejpeg($thumbnail, $targetPath, 85);
break;
case IMAGETYPE_PNG:
$success = imagepng($thumbnail, $targetPath);
break;
case IMAGETYPE_GIF:
$success = imagegif($thumbnail, $targetPath);
break;
case IMAGETYPE_WEBP:
$success = imagewebp($thumbnail, $targetPath);
break;
}
imagedestroy($sourceImage);
imagedestroy($thumbnail);
return $success;
}
/**
* Checks if a mime type is an image.
*/
function isImage(string $mimeType): bool {
return str_starts_with($mimeType, 'image/');
}
/**
* Checks if a mime type is a video.
*/
function isVideo(string $mimeType): bool {
return str_starts_with($mimeType, 'video/');
}