First commit. Implement a very basic CDN server to serve and resize images

This commit is contained in:
Lewis Dale committed 2023-08-25 20:50:52 +01:00
commit 9907bde834
10 files changed
+1333

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace ImageResizer\Lib;
use ImageResizer\Models\Image;
use ImageResizer\Models\ResizeParams;
interface ImageDb
{
public function findImage(string $path, ResizeParams $params): Image|null;
public function saveImage(
string $path,
ResizeParams $params,
string $content,
): void;
}
+55
View File
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace ImageResizer\Lib;
use ImageResizer\Models\ResizeParams;
use ImageResizer\Models\Image;
class Resizer
{
public function __construct(
private readonly ImageDb $imageDb
)
{}
/**
* @throws \Exception
*/
public function performResize(string $path, ResizeParams $params)
{
// Check if the image has already been processed
if ($image = $this->imageDb->findImage($path, $params)) {
header("Content-type: {${$image->getMime()}}");
return base64_decode($image->encode(75));
}
// Fetch the image at the given URL
$original_img = Image::fromUrl($_ENV['root_domain'] . $path);
$converted = $this->createVariant($original_img, $params);
// Store the image in the database
$this->imageDb->saveImage(
$path,
$params,
$converted
);
header("Content-type: {$original_img->getMime()}");
return base64_decode($converted);
}
private function createVariant(Image $original, ResizeParams $params): string
{
$quality = $params->quality ?: -1;
if ($params->width) {
$original->toWidth($params->width);
}
return $original->encode($quality);
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace ImageResizer\Lib;
use ImageResizer\Models\Image;
use ImageResizer\Models\ResizeParams;
class SqliteImageDb implements ImageDb {
public function __construct(
private readonly \PDO $db
) {
$this->up();
}
private function up() {
$this->db->exec('CREATE TABLE IF NOT EXISTS images (
id INTEGER PRIMARY KEY,
path TEXT NOT NULL,
width INTEGER NULLABLE,
height INTEGER NULLABLE,
quality INTEGER NULLABLE,
content TEXT NOT NULL
)');
}
public function findImage(string $path, ResizeParams $params): Image | null {
$stmt = $this->db->prepare('SELECT * FROM images WHERE path = :path AND width = :width AND height = :height AND quality = :quality');
$stmt->execute([
':path' => $path,
':width' => $params->width,
':height' => $params->height,
':quality' => $params->quality
]);
$result = $stmt->fetchObject();
return $result ? Image::fromString(base64_decode($result->content)) : null;
}
public function saveImage(
string $path,
ResizeParams $params,
string $content,
): void {
$stmt = $this->db->prepare("INSERT INTO images (path, width, height, quality, content) VALUES (:path, :width, :height, :quality, :content)"
);
$stmt->execute([
':path' => $path,
':width' => $params->width,
':height' => $params->height,
':quality' => $params->quality,
':content' => $content
]);
}
}