2022-01-08 16:22:16 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class thumb {
|
|
|
|
protected string $imagedir;
|
|
|
|
protected string $thumbdir;
|
2022-02-11 16:19:03 +00:00
|
|
|
protected string $thumburl;
|
2022-01-08 16:22:16 +00:00
|
|
|
|
|
|
|
protected int $w = 200;
|
|
|
|
protected int $h = 200;
|
|
|
|
|
2023-12-09 08:59:42 +00:00
|
|
|
protected string $ffmpeg_cmd = '/usr/bin/ffmpeg';
|
2023-12-09 08:52:46 +00:00
|
|
|
protected string $ffprobe_cmd = '/usr/bin/ffprobe';
|
|
|
|
|
2022-01-08 16:22:16 +00:00
|
|
|
const IMAGE_HANDLERS = [
|
|
|
|
IMAGETYPE_JPEG => [
|
|
|
|
'load' => 'imagecreatefromjpeg',
|
|
|
|
],
|
|
|
|
IMAGETYPE_PNG => [
|
|
|
|
'load' => 'imagecreatefrompng',
|
|
|
|
],
|
|
|
|
IMAGETYPE_GIF => [
|
|
|
|
'load' => 'imagecreatefromgif',
|
|
|
|
],
|
|
|
|
IMAGETYPE_WEBP => [
|
|
|
|
'load' => 'imagecreatefromwebp',
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
2022-02-11 16:19:03 +00:00
|
|
|
public function __construct($idir, $tdir, $turl, $width, $heigth) {
|
2022-01-08 16:22:16 +00:00
|
|
|
$this->imagedir = $idir;
|
|
|
|
$this->thumbdir = $tdir;
|
2022-02-11 16:19:03 +00:00
|
|
|
$this->thumburl = $turl;
|
2022-01-08 16:22:16 +00:00
|
|
|
$this->w = $width;
|
|
|
|
$this->h = $heigth;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function get_thumb($iname) {
|
|
|
|
$src = $this->imagedir.$iname;
|
2022-02-11 12:20:52 +00:00
|
|
|
$dstname = hash('sha256', $src);
|
2022-08-10 19:22:40 +00:00
|
|
|
$dstpath = $this->thumbdir.$dstname.'.jpg';
|
2022-01-08 16:22:16 +00:00
|
|
|
|
|
|
|
if (!file_exists($dstpath)) {
|
2023-12-06 15:40:43 +00:00
|
|
|
|
|
|
|
if(str_starts_with(mime_content_type($src), 'video/')) {
|
2023-12-09 08:52:46 +00:00
|
|
|
$cmd = $this->ffprobe_cmd.' -i "'.$src.'" -show_entries format=duration -v quiet -of csv="p=0"';
|
|
|
|
exec($cmd, $output, $retval);
|
|
|
|
$seconds = ($output[0]*10) / 100;
|
|
|
|
|
|
|
|
$cmd = $this->ffmpeg_cmd.' -i "'.$src.'" -an -ss '.$seconds.' -t 00:00:01 -vf scale=w='.$this->w.':h='.$this->h.':force_original_aspect_ratio=decrease -r 1 -y -vcodec mjpeg -f mjpeg '.$dstpath.' 2>&1';
|
|
|
|
exec($cmd, $output, $retval);
|
|
|
|
|
|
|
|
if ($retval) {
|
|
|
|
return "img/video.png";
|
|
|
|
} else {
|
|
|
|
return $this->thumburl.$dstname.'.jpg';
|
|
|
|
}
|
2023-12-06 15:40:43 +00:00
|
|
|
}
|
|
|
|
|
2022-01-08 16:22:16 +00:00
|
|
|
$type = exif_imagetype($src);
|
2022-02-11 16:13:20 +00:00
|
|
|
if ($type == 0) {
|
|
|
|
error_log("$src: Unknown Image Type");
|
|
|
|
return "img/error.png";
|
|
|
|
}
|
|
|
|
|
2022-01-08 16:22:16 +00:00
|
|
|
$image = call_user_func(self::IMAGE_HANDLERS[$type]['load'], $src);
|
|
|
|
|
2022-07-12 07:51:16 +00:00
|
|
|
if ($image == false) {
|
|
|
|
error_log("$src: Image Loading Failed");
|
|
|
|
return "img/error.png";
|
|
|
|
}
|
|
|
|
|
2022-01-08 16:22:16 +00:00
|
|
|
$srcwidth = imagesx($image);
|
|
|
|
$srcheight = imagesy($image);
|
|
|
|
|
|
|
|
|
|
|
|
$ratio = min($this->w / $srcwidth, $this->h / $srcheight);
|
|
|
|
$width = round($srcwidth*$ratio);
|
|
|
|
$height = round($srcheight*$ratio);
|
|
|
|
|
|
|
|
$thumbnail = imagecreatetruecolor($width, $height);
|
|
|
|
|
|
|
|
if ($type == IMAGETYPE_GIF || $type == IMAGETYPE_PNG) {
|
|
|
|
imagecolortransparent($thumbnail, imagecolorallocate($thumbnail, 0, 0, 0));
|
|
|
|
if ($type == IMAGETYPE_PNG) {
|
|
|
|
imagealphablending($thumbnail, false);
|
|
|
|
imagesavealpha($thumbnail, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $width, $height, $srcwidth, $srcheight);
|
2022-08-10 19:22:40 +00:00
|
|
|
call_user_func('imagejpeg',$thumbnail,$dstpath,100);
|
2022-01-08 16:22:16 +00:00
|
|
|
imagedestroy($image);
|
|
|
|
imagedestroy($thumbnail);
|
|
|
|
}
|
2022-08-10 19:22:40 +00:00
|
|
|
return $this->thumburl.$dstname.'.jpg';
|
2022-01-08 16:22:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
?>
|