aboutsummaryrefslogtreecommitdiffstats
path: root/core/Controller
diff options
context:
space:
mode:
authorRoeland Jago Douma <roeland@famdouma.nl>2017-10-19 16:22:43 +0200
committerRoeland Jago Douma <roeland@famdouma.nl>2017-11-29 14:23:15 +0100
commit604596ec166602117aaf51e86b7138a519b62742 (patch)
treee2a088bcc11b1e87414c6ed2abce16ffbf2bc6fe /core/Controller
parent6097b74970b6a9cb87d79f0c9fd3aba01cd49aa7 (diff)
downloadnextcloud-server-604596ec166602117aaf51e86b7138a519b62742.tar.gz
nextcloud-server-604596ec166602117aaf51e86b7138a519b62742.zip
Always generate avatar
Even if no avatar is set we should just generate the image. This to not duplicate the code on all the clients. And only server images from the avtar endpoint. Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'core/Controller')
-rw-r--r--core/Controller/AvatarController.php160
1 files changed, 155 insertions, 5 deletions
diff --git a/core/Controller/AvatarController.php b/core/Controller/AvatarController.php
index 36b12fbd79c..5b762a4fd3f 100644
--- a/core/Controller/AvatarController.php
+++ b/core/Controller/AvatarController.php
@@ -111,6 +111,136 @@ class AvatarController extends Controller {
$this->timeFactory = $timeFactory;
}
+
+ /**
+ * @param int $r
+ * @param int $g
+ * @param int $b
+ * @return double[] Array containing h s l in [0, 1] range
+ */
+ private function rgbToHsl($r, $g, $b) {
+ $r /= 255.0;
+ $g /= 255.0;
+ $b /= 255.0;
+
+ $max = max($r, $g, $b);
+ $min = min($r, $g, $b);
+
+
+ $h = ($max + $min) / 2.0;
+ $l = ($max + $min) / 2.0;
+
+ if($max === $min) {
+ $h = $s = 0; // Achromatic
+ } else {
+ $d = $max - $min;
+ $s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min);
+ switch($max) {
+ case $r:
+ $h = ($g - $b) / $d + ($g < $b ? 6 : 0);
+ break;
+ case $g:
+ $h = ($b - $r) / $d + 2.0;
+ break;
+ case $b:
+ $h = ($r - $g) / $d + 4.0;
+ break;
+ }
+ $h /= 6.0;
+ }
+ return [$h, $s, $l];
+
+ }
+
+ /**
+ * @param string $text
+ * @return int[] Array containting r g b in the range [0, 255]
+ */
+ private function avatarBackgroundColor($text) {
+ $hash = preg_replace('/[^0-9a-f]+/', '', $text);
+
+ $hash = md5($hash);
+ $hashChars = str_split($hash);
+
+
+ // Init vars
+ $result = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'];
+ $rgb = [0, 0, 0];
+ $sat = 0.70;
+ $lum = 0.68;
+ $modulo = 16;
+
+
+ // Splitting evenly the string
+ foreach($hashChars as $i => $char) {
+ $result[$i % $modulo] .= intval($char, 16);
+ }
+
+ // Converting our data into a usable rgb format
+ // Start at 1 because 16%3=1 but 15%3=0 and makes the repartition even
+ for($count = 1; $count < $modulo; $count++) {
+ $rgb[$count%3] += (int)$result[$count];
+ }
+
+ // Reduce values bigger than rgb requirements
+ $rgb[0] %= 255;
+ $rgb[1] %= 255;
+ $rgb[2] %= 255;
+
+ $hsl = $this->rgbToHsl($rgb[0], $rgb[1], $rgb[2]);
+
+ // Classic formulla to check the brigtness for our eye
+ // If too bright, lower the sat
+ $bright = sqrt(0.299 * ($rgb[0] ** 2) + 0.587 * ($rgb[1] ** 2) + 0.114 * ($rgb[2] ** 2));
+ if ($bright >= 200) {
+ $sat = 0.60;
+ }
+
+ return $this->hslToRgb($hsl[0], $sat, $lum);
+ }
+
+ /**
+ * @param double $h Heu in range [0, 1]
+ * @param double $s Saturation in range [0, 1]
+ * @param double $l Lightness in range [0, 1]
+ * @return int[] Array containging r g b in the range [0, 255]
+ */
+ private function hslToRgb($h, $s, $l){
+ $hue2rgb = function ($p, $q, $t){
+ if($t < 0) {
+ $t += 1;
+ }
+ if($t > 1) {
+ $t -= 1;
+ }
+ if($t < 1/6) {
+ return $p + ($q - $p) * 6 * $t;
+ }
+ if($t < 1/2) {
+ return $q;
+ }
+ if($t < 2/3) {
+ return $p + ($q - $p) * (2/3 - $t) * 6;
+ }
+ return $p;
+ };
+
+ if($s == 0){
+ $r = $l;
+ $g = $l;
+ $b = $l; // achromatic
+ }else{
+ $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
+ $p = 2 * $l - $q;
+ $r = $hue2rgb($p, $q, $h + 1/3);
+ $g = $hue2rgb($p, $q, $h);
+ $b = $hue2rgb($p, $q, $h - 1/3);
+ }
+
+ return array(round($r * 255), round($g * 255), round($b * 255));
+ }
+
+
/**
* @NoAdminRequired
* @NoCSRFRequired
@@ -135,11 +265,31 @@ class AvatarController extends Controller {
['Content-Type' => $avatar->getMimeType()]);
} catch (NotFoundException $e) {
$user = $this->userManager->get($userId);
- $resp = new JSONResponse([
- 'data' => [
- 'displayname' => $user->getDisplayName(),
- ],
- ]);
+ $userDisplayName = $user->getDisplayName();
+ $text = strtoupper(substr($userDisplayName, 0, 1));
+ $backgroundColor = $this->avatarBackgroundColor($userDisplayName);
+
+ $im = imagecreatetruecolor($size, $size);
+ $background = imagecolorallocate($im, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
+ $white = imagecolorallocate($im, 255, 255, 255);
+ imagefilledrectangle($im, 0, 0, $size, $size, $background);
+
+ $font = __DIR__ . '/../../core/fonts/OpenSans-Light.woff';
+
+ $fontSize = $size * 0.4;
+ $box = imagettfbbox($fontSize, 0, $font, $text);
+
+ $x = ($size - ($box[2] - $box[0])) / 2;
+ $y = ($size - ($box[1] - $box[7])) / 2;
+ $y -= $box[7];
+ imagettftext($im, $fontSize, 0, $x, $y, $white, $font, $text);
+
+ header('Content-Type: image/png');
+
+ imagepng($im);
+ imagedestroy($im);
+
+ exit();
} catch (\Exception $e) {
$resp = new JSONResponse([
'data' => [