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]
|
||||
dbPath=./db.sqlite
|
||||
filesPath=./files/
|
||||
thumbsPath=./files/
|
||||
mediaPath=./public_html/media/
|
||||
title=szurubooru
|
||||
|
||||
[browsing]
|
||||
postsPerPage=20
|
||||
thumbWidth=150
|
||||
thumbHeight=150
|
||||
thumbStyle=outside
|
||||
|
||||
[registration]
|
||||
emailActivation = 0
|
||||
adminActivation = 0
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
background-image: url('../img/thumb-unavailable.png');
|
||||
background-image: url('../img/thumb-upload.png');
|
||||
border: 1px solid black;
|
||||
vertical-align: middle;
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /posts
|
||||
* @route /posts/{query}
|
||||
|
@ -31,23 +33,32 @@ class PostController
|
|||
|
||||
$page = 1;
|
||||
$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 privileges]
|
||||
|
||||
$whereSql = 'WHERE safety IN (' . R::genSlots($allowedSafety) . ')';
|
||||
$params = array_merge($params, $allowedSafety);
|
||||
|
||||
//todo construct WHERE based on filters
|
||||
$whereSql = '';
|
||||
|
||||
//todo construct ORDER based on filers
|
||||
$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);
|
||||
$this->context->transport->posts = $posts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /post/upload
|
||||
*/
|
||||
|
@ -123,12 +134,12 @@ class PostController
|
|||
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
||||
R::store($dbPost);
|
||||
|
||||
//todo: generate thumbnail
|
||||
|
||||
$this->context->transport->success = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Action that decorates the page containing the post.
|
||||
* @route /post/{id}
|
||||
|
@ -146,6 +157,82 @@ class PostController
|
|||
$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.
|
||||
* @route /post/retrieve/{name}
|
||||
|
@ -171,6 +258,8 @@ class PostController
|
|||
$this->context->transport->filePath = $path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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 foreach ($this->context->transport->posts as $post): ?>
|
||||
<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>
|
||||
<?php endforeach ?>
|
||||
<?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