From 20893cc3b335049a144a53be24eaacb2e33a1480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Tue, 29 Apr 2014 17:07:10 +0200 Subject: [PATCH 1/2] Images on public sharing get downscaled to increase use experience - this will speed up loading time - adding keep aspect to core/ajax/preview.php - remove duplicate method Preview::show() - no more hard coded mimetype of preview - remove .png from the preview urls - keep old route preview.png for backwards compatibility - aspect preserving previews are now cached --- apps/files_sharing/ajax/publicpreview.php | 8 ++- apps/files_sharing/appinfo/routes.php | 8 +-- apps/files_sharing/templates/public.php | 5 +- apps/files_trashbin/appinfo/routes.php | 5 +- apps/files_versions/appinfo/routes.php | 3 +- core/ajax/preview.php | 8 ++- core/routes.php | 2 + lib/private/preview.php | 60 ++++++++++++++++------- lib/private/preview/image.php | 3 +- lib/private/preview/mp3.php | 2 +- lib/private/preview/pdf.php | 1 + lib/private/preview/provider.php | 1 + lib/private/preview/svg.php | 3 +- 13 files changed, 77 insertions(+), 32 deletions(-) diff --git a/apps/files_sharing/ajax/publicpreview.php b/apps/files_sharing/ajax/publicpreview.php index d12d212a2e..d8c892f1b7 100644 --- a/apps/files_sharing/ajax/publicpreview.php +++ b/apps/files_sharing/ajax/publicpreview.php @@ -16,6 +16,7 @@ $maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '36'; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true; $token = array_key_exists('t', $_GET) ? (string) $_GET['t'] : ''; +$keepAspect = array_key_exists('a', $_GET) ? true : false; if($token === ''){ \OC_Response::setStatus(400); //400 Bad Request @@ -70,6 +71,10 @@ if(substr($path, 0, 1) === '/') { $path = substr($path, 1); } +if ($keepAspect === true) { + $maxY = $maxX; +} + if($maxX === 0 || $maxY === 0) { \OC_Response::setStatus(400); //400 Bad Request \OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG); @@ -84,8 +89,9 @@ try{ $preview->setMaxX($maxX); $preview->setMaxY($maxY); $preview->setScalingUp($scalingUp); + $preview->setKeepAspect($keepAspect); - $preview->show(); + $preview->showPreview(); } catch (\Exception $e) { \OC_Response::setStatus(500); \OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG); diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php index 06e454b7d7..7c2834dc9c 100644 --- a/apps/files_sharing/appinfo/routes.php +++ b/apps/files_sharing/appinfo/routes.php @@ -1,9 +1,9 @@ create('core_ajax_public_preview', '/publicpreview.png')->action( -function() { - require_once __DIR__ . '/../ajax/publicpreview.php'; -}); +$this->create('core_ajax_public_preview', '/publicpreview')->action( + function() { + require_once __DIR__ . '/../ajax/publicpreview.php'; + }); // OCS API diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index f3c75134a5..7614e122e8 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -30,7 +30,10 @@
- +
diff --git a/apps/files_trashbin/appinfo/routes.php b/apps/files_trashbin/appinfo/routes.php index b1c3f02741..42398a06c8 100644 --- a/apps/files_trashbin/appinfo/routes.php +++ b/apps/files_trashbin/appinfo/routes.php @@ -1,5 +1,6 @@ create('core_ajax_trashbin_preview', '/preview.png')->action( +/** @var $this \OCP\Route\IRouter */ +$this->create('core_ajax_trashbin_preview', '/preview')->action( function() { require_once __DIR__ . '/../ajax/preview.php'; -}); \ No newline at end of file +}); diff --git a/apps/files_versions/appinfo/routes.php b/apps/files_versions/appinfo/routes.php index 8d2abaa89e..80fe0e5d61 100644 --- a/apps/files_versions/appinfo/routes.php +++ b/apps/files_versions/appinfo/routes.php @@ -8,7 +8,8 @@ // Register with the capabilities API 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() { require_once __DIR__ . '/../ajax/preview.php'; }); diff --git a/core/ajax/preview.php b/core/ajax/preview.php index 526719e8a1..d38043707a 100644 --- a/core/ajax/preview.php +++ b/core/ajax/preview.php @@ -11,6 +11,7 @@ $file = array_key_exists('file', $_GET) ? (string)$_GET['file'] : ''; $maxX = array_key_exists('x', $_GET) ? (int)$_GET['x'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36'; $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; if ($file === '') { @@ -20,6 +21,10 @@ if ($file === '') { exit; } +if ($keepAspect === true) { + $maxY = $maxX; +} + if ($maxX === 0 || $maxY === 0) { //400 Bad Request \OC_Response::setStatus(400); @@ -36,9 +41,10 @@ try { $preview->setMaxX($maxX); $preview->setMaxY($maxY); $preview->setScalingUp($scalingUp); + $preview->setKeepAspect($keepAspect); } - $preview->show(); + $preview->showPreview(); } catch (\Exception $e) { \OC_Response::setStatus(500); \OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG); diff --git a/core/routes.php b/core/routes.php index 74be880612..5368fd4564 100644 --- a/core/routes.php +++ b/core/routes.php @@ -66,6 +66,8 @@ $this->create('core_tags_delete', '/tags/{type}/delete') $this->create('js_config', '/core/js/oc.js') ->actionInclude('core/js/config.php'); // Routing +$this->create('core_ajax_preview', '/core/preview') + ->actionInclude('core/ajax/preview.php'); $this->create('core_ajax_preview', '/core/preview.png') ->actionInclude('core/ajax/preview.php'); $this->create('core_lostpassword_index', '/lostpassword/') diff --git a/lib/private/preview.php b/lib/private/preview.php index cdf2224038..361073a091 100755 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -43,6 +43,7 @@ class Preview { private $maxY; private $scalingUp; private $mimeType; + private $keepAspect = false; //filemapper used for deleting previews // index is path, value is fileinfo @@ -267,6 +268,11 @@ class Preview { return $this; } + public function setKeepAspect($keepAspect) { + $this->keepAspect = $keepAspect; + return $this; + } + /** * @brief check if all parameters are valid * @return bool @@ -297,7 +303,7 @@ class Preview { if($fileInfo !== null && $fileInfo !== false) { $fileId = $fileInfo->getId(); - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/' . $this->getMaxX() . '-' . $this->getMaxY() . '.png'; + $previewPath = $this->buildCachePath($fileId); return $this->userView->unlink($previewPath); } return false; @@ -330,15 +336,12 @@ class Preview { if (is_null($fileId)) { return false; } - - $maxX = $this->getMaxX(); - $maxY = $this->getMaxY(); - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + $preview = $this->buildCachePath($fileId); //does a preview with the wanted height and width already exist? - if ($this->userView->file_exists($previewPath . $maxX . '-' . $maxY . '.png')) { - return $previewPath . $maxX . '-' . $maxY . '.png'; + if ($this->userView->file_exists($preview)) { + return $preview; } return $this->isCachedBigger($fileId); @@ -355,6 +358,11 @@ class Preview { 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(); //array for usable cached thumbnails @@ -466,12 +474,12 @@ class Preview { $fileId = $fileInfo->getId(); $cached = $this->isCached($fileId); - if ($cached) { $stream = $this->userView->fopen($cached, 'r'); $image = new \OC_Image(); $image->loadFromFileHandle($stream); $this->preview = $image->valid() ? $image : null; + $this->resizeAndCrop(); fclose($stream); } @@ -497,7 +505,7 @@ class Preview { $this->resizeAndCrop(); $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; - $cachePath = $previewPath . $maxX . '-' . $maxY . '.png'; + $cachePath = $this->buildCachePath($fileId); if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { $this->userView->mkdir($this->getThumbnailsFolder() . '/'); @@ -524,20 +532,12 @@ class Preview { * @brief show preview * @return void */ - public function showPreview() { + public function showPreview($mimeType = null) { \OCP\Response::enableCaching(3600 * 24); // 24 hours if (is_null($this->preview)) { $this->getPreview(); } - $this->preview->show('image/png'); - } - - /** - * @brief show preview - * @return void - */ - public function show() { - $this->showPreview(); + $this->preview->show($mimeType); } /** @@ -561,6 +561,11 @@ class Preview { $realX = (int)$image->width(); $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) { $this->preview = $image; return; @@ -743,4 +748,21 @@ class Preview { } 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; + } } diff --git a/lib/private/preview/image.php b/lib/private/preview/image.php index 84343df260..59aaa27ef3 100644 --- a/lib/private/preview/image.php +++ b/lib/private/preview/image.php @@ -31,6 +31,7 @@ class Image extends Provider { return $image->valid() ? $image : false; } + } -\OC\Preview::registerProvider('OC\Preview\Image'); \ No newline at end of file +\OC\Preview::registerProvider('OC\Preview\Image'); diff --git a/lib/private/preview/mp3.php b/lib/private/preview/mp3.php index 3fc0ab0490..21f160fd50 100644 --- a/lib/private/preview/mp3.php +++ b/lib/private/preview/mp3.php @@ -47,4 +47,4 @@ class MP3 extends Provider { } -\OC\Preview::registerProvider('OC\Preview\MP3'); \ No newline at end of file +\OC\Preview::registerProvider('OC\Preview\MP3'); diff --git a/lib/private/preview/pdf.php b/lib/private/preview/pdf.php index 064a5a3b3d..4b88b1a31e 100644 --- a/lib/private/preview/pdf.php +++ b/lib/private/preview/pdf.php @@ -40,6 +40,7 @@ if (extension_loaded('imagick')) { //check if image object is valid return $image->valid() ? $image : false; } + } \OC\Preview::registerProvider('OC\Preview\PDF'); diff --git a/lib/private/preview/provider.php b/lib/private/preview/provider.php index 88337d64e4..f769823f6e 100644 --- a/lib/private/preview/provider.php +++ b/lib/private/preview/provider.php @@ -22,4 +22,5 @@ abstract class Provider { * OC_Image object of the preview */ abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); + } diff --git a/lib/private/preview/svg.php b/lib/private/preview/svg.php index 505122fddb..82ef3cdebf 100644 --- a/lib/private/preview/svg.php +++ b/lib/private/preview/svg.php @@ -45,8 +45,9 @@ if (extension_loaded('imagick')) { //check if image object is valid return $image->valid() ? $image : false; } + } \OC\Preview::registerProvider('OC\Preview\SVG'); } -} \ No newline at end of file +} From d163441f3e1d011c117eca54eb9d23c0b58a23a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 2 May 2014 18:36:58 +0200 Subject: [PATCH 2/2] load image via javascript and use $(document).width() to determine the proper side of the image to be returned --- apps/files_sharing/js/public.js | 112 ++++++++++++++---------- apps/files_sharing/templates/public.php | 4 - 2 files changed, 65 insertions(+), 51 deletions(-) diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index ae2412f6a3..0b4dec8176 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -12,10 +12,11 @@ $(document).ready(function() { + var mimetype = $('#mimetype').val(); + if (typeof FileActions !== 'undefined') { - var mimetype = $('#mimetype').val(); // 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 var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ); if (typeof action !== 'undefined') { @@ -24,57 +25,74 @@ $(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.attr('src', OC.filePath('files_sharing', 'ajax', 'publicpreview.php') + '?' + OC.buildQueryString(params)); + img.appendTo('#imgframe'); + } + // override since the format is different - Files.getDownloadUrl = function(filename, dir) { - if ($.isArray(filename)) { - filename = JSON.stringify(filename); - } - var path = dir || FileList.getCurrentDirectory(); - var params = { - service: 'files', - t: $('#sharingToken').val(), - path: path, - files: filename, - download: null + if (typeof Files !== 'undefined') { + Files.getDownloadUrl = function(filename, dir) { + if ($.isArray(filename)) { + filename = JSON.stringify(filename); + } + var path = dir || FileList.getCurrentDirectory(); + var params = { + service: 'files', + t: $('#sharingToken').val(), + path: path, + files: filename, + download: null + }; + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); }; - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); - }; - Files.getAjaxUrl = function(action, params) { - params = params || {}; - params.t = $('#sharingToken').val(); - return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params); - }; - - FileList.linkTo = function(dir) { - var params = { - service: 'files', - t: $('#sharingToken').val(), - dir: dir + Files.getAjaxUrl = function(action, params) { + params = params || {}; + params.t = $('#sharingToken').val(); + return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params); }; - return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); - }; - Files.generatePreviewUrl = function(urlSpec) { - urlSpec.t = $('#dirToken').val(); - return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec); - }; - - var file_upload_start = $('#file_upload_start'); - file_upload_start.on('fileuploadadd', function(e, data) { - var fileDirectory = ''; - if(typeof data.files[0].relativePath !== 'undefined') { - fileDirectory = data.files[0].relativePath; - } - - // Add custom data to the upload handler - data.formData = { - requesttoken: $('#publicUploadRequestToken').val(), - dirToken: $('#dirToken').val(), - subdir: $('input#dir').val(), - file_directory: fileDirectory + FileList.linkTo = function(dir) { + var params = { + service: 'files', + t: $('#sharingToken').val(), + dir: dir + }; + return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params); }; - }); + + Files.generatePreviewUrl = function(urlSpec) { + urlSpec.t = $('#dirToken').val(); + return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec); + }; + + var file_upload_start = $('#file_upload_start'); + file_upload_start.on('fileuploadadd', function(e, data) { + var fileDirectory = ''; + if(typeof data.files[0].relativePath !== 'undefined') { + fileDirectory = data.files[0].relativePath; + } + + // Add custom data to the upload handler + data.formData = { + requesttoken: $('#publicUploadRequestToken').val(), + dirToken: $('#dirToken').val(), + subdir: $('input#dir').val(), + file_directory: fileDirectory + }; + }); + } $(document).on('click', '#directLink', function() { $(this).focus(); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 7614e122e8..9471752b6b 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -30,10 +30,6 @@
-