108 lines
3.0 KiB
PHP
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/');
|
|
}
|