Thumbnail generator
This commit is contained in:
parent
3e42cf823b
commit
7c4bd0136d
9 changed files with 155 additions and 9 deletions
|
@ -5,8 +5,16 @@ prettyPrint=1
|
||||||
[main]
|
[main]
|
||||||
dbPath=./db.sqlite
|
dbPath=./db.sqlite
|
||||||
filesPath=./files/
|
filesPath=./files/
|
||||||
|
thumbsPath=./files/
|
||||||
|
mediaPath=./public_html/media/
|
||||||
title=szurubooru
|
title=szurubooru
|
||||||
|
|
||||||
|
[browsing]
|
||||||
|
postsPerPage=20
|
||||||
|
thumbWidth=150
|
||||||
|
thumbHeight=150
|
||||||
|
thumbStyle=outside
|
||||||
|
|
||||||
[registration]
|
[registration]
|
||||||
emailActivation = 0
|
emailActivation = 0
|
||||||
adminActivation = 0
|
adminActivation = 0
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
line-height: 100px;
|
line-height: 100px;
|
||||||
background-image: url('../img/thumb-unavailable.png');
|
background-image: url('../img/thumb-upload.png');
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
BIN
public_html/media/img/thumb-swf.png
Normal file
BIN
public_html/media/img/thumb-swf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 688 B |
BIN
public_html/media/img/thumb.png
Normal file
BIN
public_html/media/img/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 948 B |
|
@ -8,6 +8,8 @@ class PostController
|
||||||
$callback();
|
$callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @route /posts
|
* @route /posts
|
||||||
* @route /posts/{query}
|
* @route /posts/{query}
|
||||||
|
@ -31,23 +33,32 @@ class PostController
|
||||||
|
|
||||||
$page = 1;
|
$page = 1;
|
||||||
$params = [];
|
$params = [];
|
||||||
$params[':limit'] = 20;
|
|
||||||
$params[':offset'] = ($page - 1) * $params[':limit'];
|
|
||||||
|
|
||||||
|
$allowedSafety = array_filter(PostSafety::getAll(), function($safety)
|
||||||
|
{
|
||||||
|
return PrivilegesHelper::confirm($this->context->user, Privilege::ListPosts, PostSafety::toString($safety));
|
||||||
|
});
|
||||||
//todo safety [user choice]
|
//todo safety [user choice]
|
||||||
//todo safety [user privileges]
|
|
||||||
|
$whereSql = 'WHERE safety IN (' . R::genSlots($allowedSafety) . ')';
|
||||||
|
$params = array_merge($params, $allowedSafety);
|
||||||
|
|
||||||
//todo construct WHERE based on filters
|
//todo construct WHERE based on filters
|
||||||
$whereSql = '';
|
|
||||||
|
|
||||||
//todo construct ORDER based on filers
|
//todo construct ORDER based on filers
|
||||||
$orderSql = 'ORDER BY upload_date DESC';
|
$orderSql = 'ORDER BY upload_date DESC';
|
||||||
|
|
||||||
$limitSql = 'LIMIT :limit OFFSET :offset';
|
$limitSql = 'LIMIT ? OFFSET ?';
|
||||||
|
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
||||||
|
$params[] = $postsPerPage;
|
||||||
|
$params[] = ($page - 1) * $postsPerPage;
|
||||||
|
|
||||||
$posts = R::findAll('post', sprintf('%s %s %s', $whereSql, $orderSql, $limitSql), $params);
|
$posts = R::findAll('post', sprintf('%s %s %s', $whereSql, $orderSql, $limitSql), $params);
|
||||||
$this->context->transport->posts = $posts;
|
$this->context->transport->posts = $posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @route /post/upload
|
* @route /post/upload
|
||||||
*/
|
*/
|
||||||
|
@ -123,12 +134,12 @@ class PostController
|
||||||
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
||||||
R::store($dbPost);
|
R::store($dbPost);
|
||||||
|
|
||||||
//todo: generate thumbnail
|
|
||||||
|
|
||||||
$this->context->transport->success = true;
|
$this->context->transport->success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that decorates the page containing the post.
|
* Action that decorates the page containing the post.
|
||||||
* @route /post/{id}
|
* @route /post/{id}
|
||||||
|
@ -146,6 +157,82 @@ class PostController
|
||||||
$this->context->transport->post = $post;
|
$this->context->transport->post = $post;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that renders the thumbnail of the requested file and sends it to user.
|
||||||
|
* @route /post/thumb/{id}
|
||||||
|
*/
|
||||||
|
public function thumbAction($id)
|
||||||
|
{
|
||||||
|
$this->context->layoutName = 'layout-file';
|
||||||
|
|
||||||
|
$post = R::findOne('post', 'id = ?', [$id]);
|
||||||
|
if (!$post)
|
||||||
|
throw new SimpleException('Invalid post ID "' . $id . '"');
|
||||||
|
|
||||||
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
|
||||||
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||||
|
|
||||||
|
$path = $this->config->main->thumbsPath . DIRECTORY_SEPARATOR . $post->name . '.png';
|
||||||
|
if (!file_exists($path))
|
||||||
|
{
|
||||||
|
$srcPath = $this->config->main->thumbsPath . DIRECTORY_SEPARATOR . $post->name;
|
||||||
|
$dstPath = $path;
|
||||||
|
$dstWidth = $this->config->browsing->thumbWidth;
|
||||||
|
$dstHeight = $this->config->browsing->thumbHeight;
|
||||||
|
|
||||||
|
switch($post->mime_type)
|
||||||
|
{
|
||||||
|
case 'image/jpeg':
|
||||||
|
$srcImage = imagecreatefromjpeg($srcPath);
|
||||||
|
break;
|
||||||
|
case 'image/png':
|
||||||
|
$srcImage = imagecreatefrompng($srcPath);
|
||||||
|
break;
|
||||||
|
case 'image/gif':
|
||||||
|
$srcImage = imagecreatefromgif($srcPath);
|
||||||
|
break;
|
||||||
|
case 'application/x-shockwave-flash':
|
||||||
|
$path = $this->config->main->mediaPath . DIRECTORY_SEPARATOR . 'img' . DIRECTORY_SEPARATOR . 'thumb-swf.png';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$path = $this->config->main->mediaPath . DIRECTORY_SEPARATOR . 'img' . DIRECTORY_SEPARATOR . 'thumb.png';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($srcImage))
|
||||||
|
{
|
||||||
|
switch ($this->config->browsing->thumbStyle)
|
||||||
|
{
|
||||||
|
case 'outside':
|
||||||
|
$dstImage = ThumbnailHelper::cropOutside($srcImage, $dstWidth, $dstHeight);
|
||||||
|
break;
|
||||||
|
case 'inside':
|
||||||
|
$dstImage = ThumbnailHelper::cropInside($srcImage, $dstWidth, $dstHeight);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new SimpleException('Unknown thumbnail crop style');
|
||||||
|
}
|
||||||
|
|
||||||
|
imagepng($dstImage, $dstPath);
|
||||||
|
imagedestroy($srcImage);
|
||||||
|
imagedestroy($dstImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_readable($path))
|
||||||
|
throw new SimpleException('Thumbnail file is not readable');
|
||||||
|
|
||||||
|
\Chibi\HeadersHelper::set('Pragma', 'public');
|
||||||
|
\Chibi\HeadersHelper::set('Cache-Control', 'max-age=86400');
|
||||||
|
\Chibi\HeadersHelper::set('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + 86400));
|
||||||
|
|
||||||
|
$this->context->transport->mimeType = 'image/png';
|
||||||
|
$this->context->transport->filePath = $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action that renders the requested file itself and sends it to user.
|
* Action that renders the requested file itself and sends it to user.
|
||||||
* @route /post/retrieve/{name}
|
* @route /post/retrieve/{name}
|
||||||
|
@ -171,6 +258,8 @@ class PostController
|
||||||
$this->context->transport->filePath = $path;
|
$this->context->transport->filePath = $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @route /favorites
|
* @route /favorites
|
||||||
*/
|
*/
|
||||||
|
|
47
src/Helpers/ThumbnailHelper.php
Normal file
47
src/Helpers/ThumbnailHelper.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
class ThumbnailHelper
|
||||||
|
{
|
||||||
|
public static function cropOutside($srcImage, $dstWidth, $dstHeight)
|
||||||
|
{
|
||||||
|
$srcWidth = imagesx($srcImage);
|
||||||
|
$srcHeight = imagesy($srcImage);
|
||||||
|
|
||||||
|
if (($dstHeight / $dstWidth) > ($srcHeight / $srcWidth))
|
||||||
|
{
|
||||||
|
$h = $srcHeight;
|
||||||
|
$w = $h * $dstWidth / $dstHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$w = $srcWidth;
|
||||||
|
$h = $w * $dstHeight / $dstWidth;
|
||||||
|
}
|
||||||
|
$x = ($srcWidth - $w) / 2;
|
||||||
|
$y = ($srcHeight - $h) / 2;
|
||||||
|
|
||||||
|
$dstImage = imagecreatetruecolor($dstWidth, $dstHeight);
|
||||||
|
imagecopyresampled($dstImage, $srcImage, 0, 0, $x, $y, $dstWidth, $dstHeight, $w, $h);
|
||||||
|
return $dstImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function cropInside($srcImage, $dstWidth, $dstHeight)
|
||||||
|
{
|
||||||
|
$srcWidth = imagesx($srcImage);
|
||||||
|
$srcHeight = imagesy($srcImage);
|
||||||
|
|
||||||
|
if (($dstHeight / $dstWidth) < ($srcHeight / $srcWidth))
|
||||||
|
{
|
||||||
|
$h = $dstHeight;
|
||||||
|
$w = $h * $srcWidth / $srcHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$w = $dstWidth;
|
||||||
|
$h = $w * $srcHeight / $srcWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dstImage = imagecreatetruecolor($w, $h);
|
||||||
|
imagecopyresampled($dstImage, $srcImage, 0, 0, 0, 0, $w, $h, $srcWidth, $srcHeight);
|
||||||
|
return $dstImage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($this->context->transport->posts as $post): ?>
|
<?php foreach ($this->context->transport->posts as $post): ?>
|
||||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $post->id]) ?>">
|
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $post->id]) ?>">
|
||||||
Post <?php echo $post->id; ?>
|
<img src="<?php echo \Chibi\UrlHelper::route('post', 'thumb', ['id' => $post->id]) ?>" alt="@<?php echo $post->id ?>"/>
|
||||||
</a>
|
</a>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
2
thumbs/.gitignore
vendored
Normal file
2
thumbs/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
Loading…
Reference in a new issue