v1.0 Initial commit of project

This commit is contained in:
2026-01-01 10:54:18 +01:00
commit 768cf78b57
990 changed files with 241213 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
<?php
namespace api\classes;
class imageProcessor
{
public $postedFile = null;
private $imageTmpPath;
private $imageInfo;
public $imageRestrictions = [
'min_width' => 100,
'max_width' => 600,
'min_height' => 100,
'max_height' => 600,
'square' => false,
'allowed_types' => ['image/png', 'image/jpeg', 'image/webp'],
'max_size_kb' => 2048, // 2MB
'transparent' => false
];
private $finalImage = null;
public function __construct($imageName)
{
if (isset($_FILES[$imageName]) && $_FILES[$imageName]['error'] === UPLOAD_ERR_OK) {
$this->postedFile = $_FILES[$imageName];
$this->imageTmpPath = $this->postedFile['tmp_name'];
$this->imageInfo = getimagesize($this->imageTmpPath);
} elseif (isset($_POST['image_base64'])) {
$base64 = $_POST['image_base64'];
if (preg_match('/^data:(image\/\w+);base64,/', $base64, $matches)) {
$mimeType = $matches[1];
$base64 = substr($base64, strpos($base64, ',') + 1);
} else {
throw new Exception('Invalid image data.');
}
$imageData = base64_decode($base64);
if ($imageData === false) {
throw new Exception('Invalid base64 image data.');
}
# Create image directly from string (no file)
$srcImage = imagecreatefromstring($imageData);
if (!$srcImage) {
throw new Exception('Failed to create image from string.');
}
# Now you can get dimensions directly
$width = imagesx($srcImage);
$height = imagesy($srcImage);
# Store $srcImage in a class property, continue processing in-memory
$this->imageResource = $srcImage;
$this->imageInfo = [
'mime' => $mimeType,
'width' => $width,
'height' => $height,
'size' => strlen($imageData)
];
}
}
public function validateAndProcess()
{
if (!$this->postedFile) {
return true;
}
$width = $this->imageInfo[0];
$height = $this->imageInfo[1];
$mime = $this->imageInfo['mime'];
$fileSizeKB = filesize($this->imageTmpPath) / 1024;
if (!in_array($mime, $this->imageRestrictions['allowed_types'])) {
throw new Exception("Invalid image type: $mime");
}
if ($fileSizeKB > $this->imageRestrictions['max_size_kb']) {
throw new Exception("Image exceeds max file size.");
}
# Resize to fit within min/max bounds
$resizedImage = $this->resizeToFitRestrictions($mime, $width, $height);
# Optionally square it
if ($this->imageRestrictions['square']) {
$resizedImage = $this->makeImageSquare($resizedImage, $mime);
}
ob_start();
switch ($mime) {
case 'image/jpeg':
imagejpeg($resizedImage);
break;
case 'image/png':
imagepng($resizedImage);
break;
case 'image/webp':
imagewebp($resizedImage);
break;
}
$this->finalImage = ob_get_clean();
imagedestroy($resizedImage);
return true;
}
private function mimeSupportsTransparency($mime)
{
return in_array($mime, ['image/png', 'image/webp']);
}
private function setTransparentCanvas($image, $width, $height)
{
// Enable alpha blending and preserve alpha channel
imagealphablending($image, false);
imagesavealpha($image, true);
// Fill the image with a fully transparent color
$transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
imagefilledrectangle($image, 0, 0, $width, $height, $transparent);
return $image;
}
private function resizeToFitRestrictions($mime, $width, $height)
{
$minW = $this->imageRestrictions['min_width'];
$maxW = $this->imageRestrictions['max_width'];
$minH = $this->imageRestrictions['min_height'];
$maxH = $this->imageRestrictions['max_height'];
$srcImage = match ($mime) {
'image/jpeg' => imagecreatefromjpeg($this->imageTmpPath),
'image/png' => imagecreatefrompng($this->imageTmpPath),
'image/webp' => imagecreatefromwebp($this->imageTmpPath),
default => throw new Exception("Unsupported image type.")
};
# Determine new size
$newWidth = $width;
$newHeight = $height;
if ($width < $minW || $width > $maxW || $height < $minH || $height > $maxH) {
# Calculate scale factor based on limits
$widthScale = ($width < $minW) ? $minW / $width : ($width > $maxW ? $maxW / $width : 1);
$heightScale = ($height < $minH) ? $minH / $height : ($height > $maxH ? $maxH / $height : 1);
# Use the smallest scale to ensure both dimensions fit
$scale = min($widthScale, $heightScale);
$newWidth = round($width * $scale);
$newHeight = round($height * $scale);
}
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
# keep transparent
if ($this->mimeSupportsTransparency($mime)) {
$this->setTransparentCanvas($resizedImage, $newWidth, $newHeight);
}
imagecopyresampled($resizedImage, $srcImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagedestroy($srcImage);
return $resizedImage;
}
private function makeImageSquare($srcImage, $mime)
{
$width = imagesx($srcImage);
$height = imagesy($srcImage);
$size = min($width, $height);
$x = ($width - $size) / 2;
$y = ($height - $size) / 2;
$squareImage = imagecreatetruecolor($size, $size);
# keep transparent
if ($this->mimeSupportsTransparency($mime)) {
$this->setTransparentCanvas($squareImage, $size, $size);
}
imagecopyresampled($squareImage, $srcImage, 0, 0, $x, $y, $size, $size, $size, $size);
imagedestroy($srcImage);
return $squareImage;
}
public function returnBase64image()
{
if ($this->finalImage) {
return base64_encode($this->finalImage);
} else {
return false;
}
}
}