From 8fb1418b3badda2aaaaa2c6c3d251156af0029c9 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Fri, 2 Jan 2015 19:43:50 +0000 Subject: [PATCH] Some thumbnail enhancements: - Allow client to cache thumbnails for 5 minutes, makes scrolling with tile view more bearable - If thumbnail size is 64px or larger, extract & use thumbnail from opendocument files, makes them look better in tile view --- .../templates/default/images/opendocument.png | Bin 0 -> 7063 bytes etemplate/thumbnail.php | 64 ++++++++++++++++++ phpgwapi/js/jsapi/egw_images.js | 3 +- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 etemplate/templates/default/images/opendocument.png diff --git a/etemplate/templates/default/images/opendocument.png b/etemplate/templates/default/images/opendocument.png new file mode 100644 index 0000000000000000000000000000000000000000..ea0634246dea9eddb335241690f26feb1f240075 GIT binary patch literal 7063 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 EA3pVMumAu6 literal 0 HcmV?d00001 diff --git a/etemplate/thumbnail.php b/etemplate/thumbnail.php index 62f79269c8..2da0940c56 100644 --- a/etemplate/thumbnail.php +++ b/etemplate/thumbnail.php @@ -155,6 +155,9 @@ function read_thumbnail($src) if ($dst) { + // Allow client to cache these, makes scrolling in filemanager much nicer + header('Pragma: private'); + header('Cache-Control: max-age=300'); header('Content-Type: '.$output_mime); readfile($dst); return true; @@ -251,10 +254,71 @@ function gd_image_load($file) return imagecreatefromwbmp($file); } } + else if ($type == 'application' && strpos($image_type,'vnd.oasis.opendocument.') === 0) + { + // OpenDocuments have thumbnails inside already + return get_opendocument_thumbnail($file); + } return false; } +/** + * Extract the thumbnail from an opendocument file and apply a colored mask + * so you can tell what type it is, and so it looks a little better in larger + * thumbnails (eg: in tiled view) + * + * Inspired by thumbnails for nautilus: + * http://bernaerts.dyndns.org/linux/76-gnome/285-gnome-shell-generate-libreoffice-thumbnail-nautilus + * + * @param string $file + * @return resource GD image + */ +function get_opendocument_thumbnail($file) +{ + // Don't bother if they're using tiny thumbnails + if(get_maxsize() < 64) return false; + + list($type, $file_type) = explode('/', egw_vfs::mime_content_type($file)); + + // Image is already there, but we can't access them directly through VFS + $ext = $mimetype == 'application/vnd.oasis.opendocument.text' ? '.odt' : '.ods'; + $archive = tempnam($GLOBALS['egw_info']['server']['temp_dir'], basename($file,$ext).'-'); + copy($file,$archive); + + $thumbnail_url = 'zip://'.$archive.'#Thumbnails/thumbnail.png'; + $image = imagecreatefromstring(file_get_contents($thumbnail_url)); + unlink($archive); + + // Mask it with a color by type + $mask = imagecreatefrompng('templates/default/images/opendocument.png'); + if($image) + { + $filter_color = array(0,0,0); + switch($file_type) + { + // Type colors from LibreOffice (https://wiki.documentfoundation.org/Design/Whiteboards/LibreOffice_Initial_Icons) + case 'vnd.oasis.opendocument.text': + $filter_color = array(2,63,98); break; + case 'vnd.oasis.opendocument.spreadsheet': + $filter_color = array(16,104,2); break; + case 'vnd.oasis.opendocument.presentation': + $filter_color = array(98,37,2); break; + case 'vnd.oasis.opendocument.graphics': + $filter_color = array(135,105,0); break; + case 'vnd.oasis.opendocument.database': + $filter_color = array(83,2,96); break; + } + if($colors[$image_type]) + { + $filter_color = $colors[$image_type]; + } + imagefilter($mask, IMG_FILTER_COLORIZE, $filter_color[0],$filter_color[1],$filter_color[2] ); + imagecopyresampled($image, $mask,0,0,0,0,imagesx($image),imagesy($image),imagesx($mask),imagesy($mask)); + } + return $image; +} + /** * Create an gd_image with transparent background. * diff --git a/phpgwapi/js/jsapi/egw_images.js b/phpgwapi/js/jsapi/egw_images.js index 4e46228c69..a7aa439dff 100644 --- a/phpgwapi/js/jsapi/egw_images.js +++ b/phpgwapi/js/jsapi/egw_images.js @@ -115,7 +115,8 @@ egw.extend('images', egw.MODULE_GLOBAL, function() { { } - else if (typeof _path == 'string' && type[0] == 'image' && type[1].match(/^(png|jpe?g|gif|bmp)$/)) + else if (typeof _path == 'string' && (type[0] == 'image' && type[1].match(/^(png|jpe?g|gif|bmp)$/) || + type[0] == 'application' && type[1].indexOf('vnd.oasis.opendocument.') === 0)) { var thsize = this.config('link_list_thumbnail') || 64; image = this.link('/etemplate/thumbnail.php',{ 'path': _path, 'thsize': thsize});