Implement thumbnail generation

This commit is contained in:
Sheldon Lee 2023-11-13 02:03:04 +08:00
parent a14e2972c6
commit 792b9c875f
2 changed files with 133 additions and 22 deletions

View File

@ -4,7 +4,25 @@ include_once __DIR__ . "/logging.php";
define("ROOT_URL", "http://localhost/");
define("ROOT_DIR", "/var/www/localhost/");
define("IMG_DIR", "img/");
define("THUMBNAIL_DIR", __DIR__ . "../thumbnails");
define("THUMBNAIL_DIR", "thumbnails/");
define("THUMBNAIL_SCRIPT", __DIR__ . "/../scripts/resize-img");
define("IMAGE_EXTENSIONS", [
'jpg',
'jpeg',
'png',
'gif',
'tiff',
'bmp',
'webp',
'svg',
]);
define("VIDEO_EXTENSIONS", [
'mp4',
]);
define("FILE_EXTENSIONS", array_merge(IMAGE_EXTENSIONS, VIDEO_EXTENSIONS));
main();
@ -20,14 +38,19 @@ function main(): void {
if ($file === ".") continue;
if ($category === "" && $file === "..") continue;
if ($category != "") $file = $category.'/'.$file;
$is_dir = is_dir(ROOT_DIR.IMG_DIR.$file);
$path = add_seperator_ab("/", $category, $file);
$is_dir = is_dir(ROOT_DIR.IMG_DIR.$path);
if (!$is_dir && !is_valid_file_type($file)) continue;
$file_item = [];
$file_item["is_dir"] = $is_dir;
$file_item["url"] = ROOT_URL.IMG_DIR.$file;
$file_item["thumbnail_url"] = create_thumbnail($file);
if ($is_dir) {
$file_item["url"] = ROOT_URL.IMG_DIR.$path;
$file_item["thumbnail_url"] = null;
} else {
$file_item["url"] = ROOT_URL.IMG_DIR.$path;
$file_item["thumbnail_url"] = create_thumbnail($category, $file);
}
array_push($array, $file_item);
}
@ -35,29 +58,55 @@ function main(): void {
echo json_encode($array);
}
function create_thumbnail(string $file): string {
return ROOT_URL.IMG_DIR.$file;
function create_thumbnail(string $category, string $file): string | null {
if (!is_image_file_type($file)) return null;
$path = add_seperator_ab("/", $category, $file);
$original_file = ROOT_DIR.IMG_DIR.$path;
$thumbnail_directory = ROOT_DIR.THUMBNAIL_DIR.IMG_DIR.add_seperator_ab("/", $category, "");
$thumbnail_file = $thumbnail_directory.$file;
if (file_exists($thumbnail_file)) {
log_print("$thumbnail_file exists, skipping gneeration");
goto return_thumbnail;
}
try {
if (!is_dir($thumbnail_directory)) mkdir($thumbnail_directory, 0777, true);
}
catch(Exception $e) {
log_error($e->getMessage());
}
log_print(THUMBNAIL_SCRIPT." '$original_file' '$thumbnail_file'");
$output = shell_exec(THUMBNAIL_SCRIPT." '$original_file' '$thumbnail_file' 2>&1");
log_print($output);
if ($output === false) {
log_error("Thumbnail failed");
return ROOT_URL.IMG_DIR.$path;
}
return_thumbnail:
return ROOT_URL.THUMBNAIL_DIR.IMG_DIR.$path;
}
function add_seperator_ab(string $separator, string $a, string $b): string {
if ($a === "") return $b;
return $a.$separator.$b;
}
function is_valid_file_type(string $filename): bool {
$file_extensions = [
// Image extensions
'jpg',
'jpeg',
'png',
'gif',
'tiff',
'bmp',
'webp',
'svg',
// Video extensions
'mp4',
];
foreach ($file_extensions as $file_extension) {
foreach (FILE_EXTENSIONS as $file_extension) {
if (str_ends_with($filename, $file_extension)) return true;
}
return false;
}
function is_image_file_type(string $filename): bool {
foreach(IMAGE_EXTENSIONS as $file_extension) {
if(str_ends_with($filename, $file_extension)) return true;
}
return false;
}
?>

62
scripts/resize-img Executable file
View File

@ -0,0 +1,62 @@
#!/usr/bin/python
from PIL import Image
import sys
def main():
target_width = 2048
argn = len(sys.argv)
if argn == 1:
print("You must specify an input file")
exit(1)
elif argn == 2:
print("You must specify an output file")
exit(1)
input_image_path = sys.argv[1]
output_image_path = sys.argv[2]
try:
image = Image.open(input_image_path)
except IOError:
print(f"Cannot open image file {input_image_path}")
exit(1)
width, height = image.size
new_height = int(target_width * height / width)
image = image.resize((target_width, new_height), Image.Resampling.BICUBIC)
image = rotate_image(image)
kwargs = {"quality": 50}
if "exif" in image.info.keys():
kwargs["exif"] = image.info["exif"]
try:
image.save(output_image_path, **kwargs)
except IOError:
print(f"Cannot save file {output_image_path}")
exit(1)
def rotate_image(image):
exif = image.getexif()
if exif is None:
return image
orientation = exif.get(0x0012, 1) # 0x0112 is the EXIF code for orientation
if orientation == 1:
return image
elif orientation == 3:
image = image.rotate(180, expand=True)
elif orientation == 6:
image = image.rotate(270, expand=True)
elif orientation == 8:
image = image.rotate(90, expand=True)
return image
if __name__ == "__main__":
main()