= 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/'); }