diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-01-19 15:47:05 +0100 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-05-21 20:36:21 +0200 |
commit | 0211feb94647a0e329030b66bc4c5b4304d10a0f (patch) | |
tree | 3f139ef19ccf443b42188e7bcf43e63a99b88449 /apps/theming | |
parent | 5ae18ee06ebbc693e9fae93bf9e0078f699068f3 (diff) | |
download | nextcloud-server-0211feb94647a0e329030b66bc4c5b4304d10a0f.tar.gz nextcloud-server-0211feb94647a0e329030b66bc4c5b4304d10a0f.zip |
fix(theming): Also set default background color ("primary") for custom images
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'apps/theming')
-rw-r--r-- | apps/theming/lib/Service/BackgroundService.php | 66 | ||||
-rw-r--r-- | apps/theming/lib/Themes/CommonThemeTrait.php | 3 |
2 files changed, 67 insertions, 2 deletions
diff --git a/apps/theming/lib/Service/BackgroundService.php b/apps/theming/lib/Service/BackgroundService.php index 1b948c7300a..fb0563b1d5c 100644 --- a/apps/theming/lib/Service/BackgroundService.php +++ b/apps/theming/lib/Service/BackgroundService.php @@ -213,7 +213,6 @@ class BackgroundService { * @throws NoUserException */ public function setFileBackground($path): void { - $this->config->setUserValue($this->userId, Application::APP_ID, 'background_image', self::BACKGROUND_CUSTOM); $userFolder = $this->rootFolder->getUserFolder($this->userId); /** @var File $file */ @@ -224,7 +223,13 @@ class BackgroundService { throw new InvalidArgumentException('Invalid image file'); } + $meanColor = $this->calculateMeanColor($image); + if ($meanColor !== false) { + $this->setColorBackground($meanColor); + } + $this->getAppDataFolder()->newFile('background.jpg', $file->fopen('r')); + $this->config->setUserValue($this->userId, Application::APP_ID, 'background_image', self::BACKGROUND_CUSTOM); } public function setShippedBackground($fileName): void { @@ -235,6 +240,9 @@ class BackgroundService { $this->setColorBackground(self::SHIPPED_BACKGROUNDS[$fileName]['primary_color']); } + /** + * Set the background to color only + */ public function setColorBackground(string $color): void { if (!preg_match('/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $color)) { throw new InvalidArgumentException('The given color is invalid'); @@ -276,4 +284,60 @@ class BackgroundService { return $rootFolder->newFolder($this->userId); } } + + /** + * Calculate mean color of an given image + * It only takes the upper part into account so that a matching text color can be derived for the app menu + */ + private function calculateMeanColor(\OCP\Image $image): false|string { + /** + * Small helper to ensure one channel is returned as 8byte hex + */ + function toHex(int $channel) { + $hex = dechex($channel); + return match (strlen($hex)) { + 0 => '00', + 1 => '0'.$hex, + 2 => $hex, + default => 'ff', + }; + } + + $tempImage = new \OCP\Image(); + + // Crop to only analyze top bar + $resource = $image->cropNew(0, 0, $image->width(), min(max(50, (int)($image->height() * 0.125)), $image->height())); + if ($resource === false) { + return false; + } + + $tempImage->setResource($resource); + if (!$tempImage->preciseResize(100, 7)) { + return false; + } + + $resource = $tempImage->resource(); + if ($resource === false) { + return false; + } + + $reds = []; + $greens = []; + $blues = []; + for ($y = 0; $y < 7; $y++) { + for ($x = 0; $x < 100; $x++) { + $value = imagecolorat($resource, $x, $y); + if ($value === false) { + continue; + } + $reds[] = ($value >> 16) & 0xFF; + $greens[] = ($value >> 8) & 0xFF; + $blues[] = $value & 0xFF; + } + } + $meanColor = '#' . toHex((int)(array_sum($reds) / count($reds))); + $meanColor .= toHex((int)(array_sum($greens) / count($greens))); + $meanColor .= toHex((int)(array_sum($blues) / count($blues))); + return $meanColor; + } } diff --git a/apps/theming/lib/Themes/CommonThemeTrait.php b/apps/theming/lib/Themes/CommonThemeTrait.php index dd5b25e1a29..cf2427e823e 100644 --- a/apps/theming/lib/Themes/CommonThemeTrait.php +++ b/apps/theming/lib/Themes/CommonThemeTrait.php @@ -151,7 +151,8 @@ trait CommonThemeTrait { $cacheBuster = substr(sha1($user->getUID() . '_' . $currentVersion), 0, 8); return [ '--image-background' => "url('" . $this->urlGenerator->linkToRouteAbsolute('theming.userTheme.getBackground') . "?v=$cacheBuster')", - '--color-background-plain' => $this->primaryColor, + '--color-background-plain' => $this->themingDefaults->getColorPrimary(), + '--background-image-invert-if-bright' => $isPrimaryBright ? 'invert(100%)' : 'no', ]; } |