diff options
author | Julius Haertl <jus@bitgrid.net> | 2016-08-14 12:24:51 +0200 |
---|---|---|
committer | Julius Haertl <jus@bitgrid.net> | 2016-11-18 10:23:22 +0100 |
commit | 2d65b8c600580cd64aa599a791a467101b873c5a (patch) | |
tree | ea138f9e88072bb220ef352f3c911264510692cd /apps/theming | |
parent | da6285b84f175640622a020f2d9258cee86a3c14 (diff) | |
download | nextcloud-server-2d65b8c600580cd64aa599a791a467101b873c5a.tar.gz nextcloud-server-2d65b8c600580cd64aa599a791a467101b873c5a.zip |
Theming: Add favicon-touch and fix icon creation with non svg images
Signed-off-by: Julius Haertl <jus@bitgrid.net>
Diffstat (limited to 'apps/theming')
-rw-r--r-- | apps/theming/appinfo/routes.php | 8 | ||||
-rw-r--r-- | apps/theming/lib/Controller/IconController.php | 96 |
2 files changed, 72 insertions, 32 deletions
diff --git a/apps/theming/appinfo/routes.php b/apps/theming/appinfo/routes.php index 1894d810287..a6511668d14 100644 --- a/apps/theming/appinfo/routes.php +++ b/apps/theming/appinfo/routes.php @@ -67,8 +67,14 @@ return ['routes' => [ 'defaults' => array("app" => "core"), ], [ + 'name' => 'Icon#getTouchIcon', + 'url' => '/icon/{app}', + 'verb' => 'GET', + 'defaults' => array("app" => "core"), + ], + [ 'name' => 'Icon#getThemedIcon', - 'url' => '/image/{app}/{image}', + 'url' => '/img/{app}/{image}', 'verb' => 'GET', 'defaults' => array("app" => "core"), 'requirements' => array('image' => '.+') diff --git a/apps/theming/lib/Controller/IconController.php b/apps/theming/lib/Controller/IconController.php index e1690c039d3..d7c27a88134 100644 --- a/apps/theming/lib/Controller/IconController.php +++ b/apps/theming/lib/Controller/IconController.php @@ -121,53 +121,87 @@ class IconController extends Controller { return $response; } + /** + * Return a 512x512 icon for touch devices + * + * @PublicPage + * @NoCSRFRequired + * + * @param $app app name + * @return StreamResponse|DataResponse + */ + public function getTouchIcon($app) { + // TODO: we need caching here + $icon = $this->renderAppIcon($app); + $icon->resizeImage(512, 512, Imagick::FILTER_LANCZOS, 1); + $icon->setImageFormat("png24"); + + $response = new DataDisplayResponse($icon, Http::STATUS_OK, ['Content-Type' => 'image/png']); + $response->cacheFor(3600); + $response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime())); + return $response; + } + + /** + * Render app icon on themed background color + * fallback to logo + * + * @param $app app name + * @return Imagick + */ private function renderAppIcon($app) { $appIcon = $this->getAppIcon($app); $color = $this->config->getAppValue($this->appName, 'color'); + $mime = mime_content_type($appIcon); if ($color === "") { $color = '#0082c9'; } - $svg = file_get_contents($appIcon); - if ($this->util->invertTextColor($color)) { - $svg = $this->svgInvert($svg); - } - // generate background image with rounded corners $background = '<?xml version="1.0" encoding="UTF-8"?>' . '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink">' . '<rect x="0" y="0" rx="75" ry="75" width="512" height="512" style="fill:' . $color . ';" />' . '</svg>'; - $tmp = new Imagick(); - $tmp->readImageBlob($svg); - $x = $tmp->getImageWidth(); - $y = $tmp->getImageHeight(); - $res = $tmp->getImageResolution(); - $tmp->destroy(); - - // convert svg to resized image - $appIconFile = new Imagick(); - $resX = (int)(512 * $res['x'] / $x * 2.53); - $resY = (int)(512 * $res['y'] / $y * 2.53); - $appIconFile->setResolution($resX, $resY); - $appIconFile->setBackgroundColor(new ImagickPixel('transparent')); - $appIconFile->readImageBlob($svg); - $appIconFile->setImageFormat("png24"); - // offset for icon positioning - $offset_w = (int)($appIconFile->getImageWidth() * 0.05); - $offset_h = (int)($appIconFile->getImageHeight() * 0.05); - // center icon if it is not square - if ($x > $y) { - $offset_h += 512 / 2 - $appIconFile->getImageHeight() / 2; - } - if ($y > $x) { - $offset_h += 512 / 2 - $appIconFile->getImageHeight() / 2; + // resize svg magic as this seems broken in Imagemagick + if($mime === "image/svg+xml") { + $svg = file_get_contents($appIcon); + if ($this->util->invertTextColor($color)) { + $svg = $this->svgInvert($svg); + } + + $tmp = new Imagick(); + $tmp->readImageBlob($svg); + $x = $tmp->getImageWidth(); + $y = $tmp->getImageHeight(); + $res = $tmp->getImageResolution(); + $tmp->destroy(); + + // convert svg to resized image + $appIconFile = new Imagick(); + $resX = (int)(512 * $res['x'] / $x * 2.53); + $resY = (int)(512 * $res['y'] / $y * 2.53); + $appIconFile->setResolution($resX, $resY); + $appIconFile->setBackgroundColor(new ImagickPixel('transparent')); + $appIconFile->readImageBlob($svg); + } else { + $appIconFile = new Imagick(); + $appIconFile->setBackgroundColor(new ImagickPixel('transparent')); + $appIconFile->readImageBlob(file_get_contents($appIcon)); + $appIconFile->scaleImage(512, 512, true); } - $innerWidth = (int)($appIconFile->getImageWidth() - $offset_w * 2); - $innerHeight = (int)($appIconFile->getImageHeight() - $offset_h * 2); + // offset for icon positioning + $border_w = (int)($appIconFile->getImageWidth() * 0.05); + $border_h = (int)($appIconFile->getImageHeight() * 0.05); + $innerWidth = (int)($appIconFile->getImageWidth() - $border_w * 2); + $innerHeight = (int)($appIconFile->getImageHeight() - $border_h * 2); $appIconFile->adaptiveResizeImage($innerWidth, $innerHeight); + // center icon + $offset_w = 512 / 2 - $innerWidth / 2; + $offset_h = 512 / 2 - $innerHeight / 2; + + $appIconFile->setImageFormat("png24"); $finalIconFile = new Imagick(); $finalIconFile->readImageBlob($background); |