Merge pull request #8407 from owncloud/scale-pics-on-public-sharing-master

Images on public sharing get downscaled to increase use experience - thi...
This commit is contained in:
Thomas Müller 2014-05-05 10:12:40 +02:00
commit 341fcdc37a
14 changed files with 138 additions and 79 deletions

View File

@ -16,6 +16,7 @@ $maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '36';
$maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '36';
$scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true;
$token = array_key_exists('t', $_GET) ? (string) $_GET['t'] : ''; $token = array_key_exists('t', $_GET) ? (string) $_GET['t'] : '';
$keepAspect = array_key_exists('a', $_GET) ? true : false;
if($token === ''){ if($token === ''){
\OC_Response::setStatus(400); //400 Bad Request \OC_Response::setStatus(400); //400 Bad Request
@ -70,6 +71,10 @@ if(substr($path, 0, 1) === '/') {
$path = substr($path, 1); $path = substr($path, 1);
} }
if ($keepAspect === true) {
$maxY = $maxX;
}
if($maxX === 0 || $maxY === 0) { if($maxX === 0 || $maxY === 0) {
\OC_Response::setStatus(400); //400 Bad Request \OC_Response::setStatus(400); //400 Bad Request
\OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG); \OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG);
@ -84,8 +89,9 @@ try{
$preview->setMaxX($maxX); $preview->setMaxX($maxX);
$preview->setMaxY($maxY); $preview->setMaxY($maxY);
$preview->setScalingUp($scalingUp); $preview->setScalingUp($scalingUp);
$preview->setKeepAspect($keepAspect);
$preview->show(); $preview->showPreview();
} catch (\Exception $e) { } catch (\Exception $e) {
\OC_Response::setStatus(500); \OC_Response::setStatus(500);
\OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG); \OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG);

View File

@ -1,9 +1,9 @@
<?php <?php
/** @var $this \OCP\Route\IRouter */ /** @var $this \OCP\Route\IRouter */
$this->create('core_ajax_public_preview', '/publicpreview.png')->action( $this->create('core_ajax_public_preview', '/publicpreview')->action(
function() { function() {
require_once __DIR__ . '/../ajax/publicpreview.php'; require_once __DIR__ . '/../ajax/publicpreview.php';
}); });
// OCS API // OCS API

View File

@ -12,10 +12,11 @@
$(document).ready(function() { $(document).ready(function() {
if (typeof FileActions !== 'undefined') {
var mimetype = $('#mimetype').val(); var mimetype = $('#mimetype').val();
if (typeof FileActions !== 'undefined') {
// Show file preview if previewer is available, images are already handled by the template // Show file preview if previewer is available, images are already handled by the template
if (mimetype.substr(0, mimetype.indexOf('/')) != 'image' && $('.publicpreview').length === 0) { if (mimetype.substr(0, mimetype.indexOf('/')) !== 'image' && $('.publicpreview').length === 0) {
// Trigger default action if not download TODO // Trigger default action if not download TODO
var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ); var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ);
if (typeof action !== 'undefined') { if (typeof action !== 'undefined') {
@ -24,7 +25,23 @@ $(document).ready(function() {
} }
} }
// dynamically load image previews
if (mimetype.substr(0, mimetype.indexOf('/')) === 'image' ) {
var params = {
x: $(document).width() * window.devicePixelRatio,
a: 'true',
file: encodeURIComponent($('#dir').val() + $('#filename').val()),
t: $('#sharingToken').val()
};
var img = $('<img class="publicpreview">');
img.attr('src', OC.filePath('files_sharing', 'ajax', 'publicpreview.php') + '?' + OC.buildQueryString(params));
img.appendTo('#imgframe');
}
// override since the format is different // override since the format is different
if (typeof Files !== 'undefined') {
Files.getDownloadUrl = function(filename, dir) { Files.getDownloadUrl = function(filename, dir) {
if ($.isArray(filename)) { if ($.isArray(filename)) {
filename = JSON.stringify(filename); filename = JSON.stringify(filename);
@ -75,6 +92,7 @@ $(document).ready(function() {
file_directory: fileDirectory file_directory: fileDirectory
}; };
}); });
}
$(document).on('click', '#directLink', function() { $(document).on('click', '#directLink', function() {
$(this).focus(); $(this).focus();

View File

@ -30,7 +30,6 @@
<?php else: ?> <?php else: ?>
<?php if (substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'image'): ?> <?php if (substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'image'): ?>
<div id="imgframe"> <div id="imgframe">
<img src="<?php p($_['downloadURL']); ?>" alt="" />
</div> </div>
<?php elseif (substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'video'): ?> <?php elseif (substr($_['mimetype'], 0, strpos($_['mimetype'], '/')) == 'video'): ?>
<div id="imgframe"> <div id="imgframe">

View File

@ -1,5 +1,6 @@
<?php <?php
$this->create('core_ajax_trashbin_preview', '/preview.png')->action( /** @var $this \OCP\Route\IRouter */
$this->create('core_ajax_trashbin_preview', '/preview')->action(
function() { function() {
require_once __DIR__ . '/../ajax/preview.php'; require_once __DIR__ . '/../ajax/preview.php';
}); });

View File

@ -8,7 +8,8 @@
// Register with the capabilities API // Register with the capabilities API
OC_API::register('get', '/cloud/capabilities', array('OCA\Files_Versions\Capabilities', 'getCapabilities'), 'files_versions', OC_API::USER_AUTH); OC_API::register('get', '/cloud/capabilities', array('OCA\Files_Versions\Capabilities', 'getCapabilities'), 'files_versions', OC_API::USER_AUTH);
$this->create('core_ajax_versions_preview', '/preview.png')->action( /** @var $this \OCP\Route\IRouter */
$this->create('core_ajax_versions_preview', '/preview')->action(
function() { function() {
require_once __DIR__ . '/../ajax/preview.php'; require_once __DIR__ . '/../ajax/preview.php';
}); });

View File

@ -11,6 +11,7 @@ $file = array_key_exists('file', $_GET) ? (string)$_GET['file'] : '';
$maxX = array_key_exists('x', $_GET) ? (int)$_GET['x'] : '36'; $maxX = array_key_exists('x', $_GET) ? (int)$_GET['x'] : '36';
$maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36';
$scalingUp = array_key_exists('scalingup', $_GET) ? (bool)$_GET['scalingup'] : true; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool)$_GET['scalingup'] : true;
$keepAspect = array_key_exists('a', $_GET) ? true : false;
$always = array_key_exists('forceIcon', $_GET) ? (bool)$_GET['forceIcon'] : true; $always = array_key_exists('forceIcon', $_GET) ? (bool)$_GET['forceIcon'] : true;
if ($file === '') { if ($file === '') {
@ -20,6 +21,10 @@ if ($file === '') {
exit; exit;
} }
if ($keepAspect === true) {
$maxY = $maxX;
}
if ($maxX === 0 || $maxY === 0) { if ($maxX === 0 || $maxY === 0) {
//400 Bad Request //400 Bad Request
\OC_Response::setStatus(400); \OC_Response::setStatus(400);
@ -36,9 +41,10 @@ try {
$preview->setMaxX($maxX); $preview->setMaxX($maxX);
$preview->setMaxY($maxY); $preview->setMaxY($maxY);
$preview->setScalingUp($scalingUp); $preview->setScalingUp($scalingUp);
$preview->setKeepAspect($keepAspect);
} }
$preview->show(); $preview->showPreview();
} catch (\Exception $e) { } catch (\Exception $e) {
\OC_Response::setStatus(500); \OC_Response::setStatus(500);
\OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG); \OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG);

View File

@ -66,6 +66,8 @@ $this->create('core_tags_delete', '/tags/{type}/delete')
$this->create('js_config', '/core/js/oc.js') $this->create('js_config', '/core/js/oc.js')
->actionInclude('core/js/config.php'); ->actionInclude('core/js/config.php');
// Routing // Routing
$this->create('core_ajax_preview', '/core/preview')
->actionInclude('core/ajax/preview.php');
$this->create('core_ajax_preview', '/core/preview.png') $this->create('core_ajax_preview', '/core/preview.png')
->actionInclude('core/ajax/preview.php'); ->actionInclude('core/ajax/preview.php');
$this->create('core_lostpassword_index', '/lostpassword/') $this->create('core_lostpassword_index', '/lostpassword/')

View File

@ -43,6 +43,7 @@ class Preview {
private $maxY; private $maxY;
private $scalingUp; private $scalingUp;
private $mimeType; private $mimeType;
private $keepAspect = false;
//filemapper used for deleting previews //filemapper used for deleting previews
// index is path, value is fileinfo // index is path, value is fileinfo
@ -267,6 +268,11 @@ class Preview {
return $this; return $this;
} }
public function setKeepAspect($keepAspect) {
$this->keepAspect = $keepAspect;
return $this;
}
/** /**
* @brief check if all parameters are valid * @brief check if all parameters are valid
* @return bool * @return bool
@ -297,7 +303,7 @@ class Preview {
if($fileInfo !== null && $fileInfo !== false) { if($fileInfo !== null && $fileInfo !== false) {
$fileId = $fileInfo->getId(); $fileId = $fileInfo->getId();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png'; $previewPath = $this->buildCachePath($fileId);
return $this->userView->unlink($previewPath); return $this->userView->unlink($previewPath);
} }
return false; return false;
@ -331,14 +337,11 @@ class Preview {
return false; return false;
} }
$maxX = $this->getMaxX(); $preview = $this->buildCachePath($fileId);
$maxY = $this->getMaxY();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
//does a preview with the wanted height and width already exist? //does a preview with the wanted height and width already exist?
if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) { if ($this->userView->file_exists($preview)) {
return $previewPath . $maxX . '-' . $maxY . '.png'; return $preview;
} }
return $this->isCachedBigger($fileId); return $this->isCachedBigger($fileId);
@ -355,6 +358,11 @@ class Preview {
return false; return false;
} }
// in order to not loose quality we better generate aspect preserving previews from the original file
if ($this->keepAspect) {
return false;
}
$maxX = $this->getMaxX(); $maxX = $this->getMaxX();
//array for usable cached thumbnails //array for usable cached thumbnails
@ -466,12 +474,12 @@ class Preview {
$fileId = $fileInfo->getId(); $fileId = $fileInfo->getId();
$cached = $this->isCached($fileId); $cached = $this->isCached($fileId);
if ($cached) { if ($cached) {
$stream = $this->userView->fopen($cached, 'r'); $stream = $this->userView->fopen($cached, 'r');
$image = new \OC_Image(); $image = new \OC_Image();
$image->loadFromFileHandle($stream); $image->loadFromFileHandle($stream);
$this->preview = $image->valid() ? $image : null; $this->preview = $image->valid() ? $image : null;
$this->resizeAndCrop(); $this->resizeAndCrop();
fclose($stream); fclose($stream);
} }
@ -497,7 +505,7 @@ class Preview {
$this->resizeAndCrop(); $this->resizeAndCrop();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
$cachePath = $previewPath . $maxX . '-' . $maxY . '.png'; $cachePath = $this->buildCachePath($fileId);
if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) {
$this->userView->mkdir($this->getThumbnailsFolder() . '/'); $this->userView->mkdir($this->getThumbnailsFolder() . '/');
@ -524,20 +532,12 @@ class Preview {
* @brief show preview * @brief show preview
* @return void * @return void
*/ */
public function showPreview() { public function showPreview($mimeType = null) {
\OCP\Response::enableCaching(3600 * 24); // 24 hours \OCP\Response::enableCaching(3600 * 24); // 24 hours
if (is_null($this->preview)) { if (is_null($this->preview)) {
$this->getPreview(); $this->getPreview();
} }
$this->preview->show('image/png'); $this->preview->show($mimeType);
}
/**
* @brief show preview
* @return void
*/
public function show() {
$this->showPreview();
} }
/** /**
@ -561,6 +561,11 @@ class Preview {
$realX = (int)$image->width(); $realX = (int)$image->width();
$realY = (int)$image->height(); $realY = (int)$image->height();
// compute $maxY using the aspect of the generated preview
if ($this->keepAspect) {
$y = $x / ($realX / $realY);
}
if ($x === $realX && $y === $realY) { if ($x === $realX && $y === $realY) {
$this->preview = $image; $this->preview = $image;
return; return;
@ -743,4 +748,21 @@ class Preview {
} }
return false; return false;
} }
/**
* @param $fileId
* @return string
*/
private function buildCachePath($fileId) {
$maxX = $this->getMaxX();
$maxY = $this->getMaxY();
$previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/';
$preview = $previewPath . $maxX . '-' . $maxY . '.png';
if ($this->keepAspect) {
$preview = $previewPath . $maxX . '-with-aspect.png';
return $preview;
}
return $preview;
}
} }

View File

@ -31,6 +31,7 @@ class Image extends Provider {
return $image->valid() ? $image : false; return $image->valid() ? $image : false;
} }
} }
\OC\Preview::registerProvider('OC\Preview\Image'); \OC\Preview::registerProvider('OC\Preview\Image');

View File

@ -40,6 +40,7 @@ if (extension_loaded('imagick')) {
//check if image object is valid //check if image object is valid
return $image->valid() ? $image : false; return $image->valid() ? $image : false;
} }
} }
\OC\Preview::registerProvider('OC\Preview\PDF'); \OC\Preview::registerProvider('OC\Preview\PDF');

View File

@ -22,4 +22,5 @@ abstract class Provider {
* OC_Image object of the preview * OC_Image object of the preview
*/ */
abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview);
} }

View File

@ -45,6 +45,7 @@ if (extension_loaded('imagick')) {
//check if image object is valid //check if image object is valid
return $image->valid() ? $image : false; return $image->valid() ? $image : false;
} }
} }
\OC\Preview::registerProvider('OC\Preview\SVG'); \OC\Preview::registerProvider('OC\Preview\SVG');