37018-vm/includes/ImageProcessor.php
2025-12-18 01:59:13 +00:00

131 lines
5.0 KiB
PHP

<?php
class ImageProcessor {
private static $uploadDir = 'assets/images/uploads/';
private static $maxWidth = 400; // Default max width for thumbnails
/**
* Handles the uploaded image, moves it to the upload directory, and resizes it.
*
* @param array $file The $_FILES array entry for the uploaded file.
* @return string|false The path to the saved thumbnail or false on error.
*/
public static function processAndSaveImage(array $file) {
if (!isset($file['tmp_name']) || $file['error'] !== UPLOAD_ERR_OK) {
error_log("ImageProcessor: No file uploaded or an error occurred. File error code: " . ($file['error'] ?? 'unknown'));
return false; // No file uploaded or an error occurred
}
// Validate file type
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($file['type'], $allowedTypes)) {
error_log("ImageProcessor: Invalid file type uploaded: " . $file['type']);
return false; // Invalid file type
}
// Ensure upload directory exists
if (!is_dir(self::$uploadDir)) {
mkdir(self::$uploadDir, 0775, true);
}
// Generate a unique file name
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$fileName = uniqid('thumbnail_') . '.' . $extension;
$targetPath = self::$uploadDir . $fileName;
// Move the uploaded file
if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
error_log("ImageProcessor: Failed to move uploaded file from " . $file['tmp_name'] . " to " . $targetPath);
return false; // Failed to move uploaded file
}
// Resize image
if (!self::resizeImage($targetPath, $file['type'])) {
error_log("ImageProcessor: Failed to resize image: " . $targetPath);
// If resizing fails, you might want to delete the original uploaded file
unlink($targetPath);
return false;
}
return $targetPath; // Return the path to the saved and resized image
}
/**
* Resizes an image to a maximum width, maintaining aspect ratio.
*
* @param string $imagePath The path to the image file.
* @param string $mimeType The MIME type of the image.
* @return bool True on success, false on failure.
*/
private static function resizeImage(string $imagePath, string $mimeType) {
list($width, $height) = getimagesize($imagePath);
if ($width <= self::$maxWidth) {
return true; // No resizing needed
}
$newWidth = self::$maxWidth;
$newHeight = (int) (self::$maxWidth * ($height / $width));
$image = null;
switch ($mimeType) {
case 'image/jpeg':
$image = imagecreatefromjpeg($imagePath);
break;
case 'image/png':
$image = imagecreatefrompng($imagePath);
break;
case 'image/gif':
$image = imagecreatefromgif($imagePath);
break;
default:
error_log("ImageProcessor: Unsupported image type for resizing: " . $mimeType);
return false; // Unsupported image type for resizing
}
if (!$image) {
return false;
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
// Preserve transparency for PNG and GIF
if ($mimeType == 'image/png') {
imagealphablending($resizedImage, false);
imagesavealpha($resizedImage, true);
$transparent = imagecolorallocatealpha($resizedImage, 255, 255, 255, 127);
imagefilledrectangle($resizedImage, 0, 0, $newWidth, $newHeight, $transparent);
} elseif ($mimeType == 'image/gif') {
$trnprt_indx = imagecolortransparent($image);
if ($trnprt_indx >= 0) {
// Get the transparent color from the original image
$trnprt_color = imagecolorsforindex($image, $trnprt_indx);
// Allocate the same color in the new image
$trnprt_indx = imagecolorallocate($resizedImage, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
imagefill($resizedImage, 0, 0, $trnprt_indx);
imagecolortransparent($resizedImage, $trnprt_indx);
}
}
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
$success = false;
switch ($mimeType) {
case 'image/jpeg':
$success = imagejpeg($resizedImage, $imagePath, 90); // 90% quality
break;
case 'image/png':
$success = imagepng($resizedImage, $imagePath);
break;
case 'image/gif':
$success = imagegif($resizedImage, $imagePath);
break;
}
imagedestroy($image);
imagedestroy($resizedImage);
return $success;
}
}