Thumbnail generator

This commit is contained in:
Marcin Kurczewski 2013-10-08 23:02:31 +02:00
parent 3e42cf823b
commit 7c4bd0136d
9 changed files with 155 additions and 9 deletions

View file

@ -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

View file

@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 688 B

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

View file

@ -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
*/

View 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;
}
}

View file

@ -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&nbsp;<?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
View file

@ -0,0 +1,2 @@
*
!.gitignore