Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ $image = $avatar->background('#ff0000')->generate();
$image = $avatar->color('#ff0000')->generate();
````

### Auto Color
````php
// Will choose a background color based on `name` and a contrasting font color. The color for a specific name will always be the same.
$image = $avatar->autoColor()->generate();
````

### Font file - default: /fonts/OpenSans-Regular.ttf
Two fonts with two variants are included:
* /fonts/OpenSans-Regular.ttf
Expand Down
132 changes: 132 additions & 0 deletions src/InitialAvatar.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,26 @@ public function color($color)
return $this;
}

/**
* Automatically set a font and/or background color based on the supplied name.
*
* @param bool $foreground
* @param bool $background
*
* @return $this
*/
public function autoColor(bool $foreground = true, bool $background = true, int $saturation = 85, int $luminance = 60)
{
$hue = (crc32($this->name) % 360) / 360;
$saturation /= 100;
$luminance /= 100;

$this->bgColor = $this->convertHSLtoRGB($hue, $saturation, $luminance);
$this->fontColor = $this->getContrastColor($this->bgColor);

return $this;
}

/**
* Set the font file by path or int (1-5).
*
Expand Down Expand Up @@ -782,4 +802,116 @@ protected function getFontByScript()

return $this->getFontFile();
}

/**
* Convert HSL color value produced by autoColor() to RGB value expected by image driver.
*/
protected function convertHSLtoRGB($h, $s, $l, $toHex = true)
{
assert((0 <= $h) && ($h <= 1));

$red = $l;
$green = $l;
$blue = $l;

$v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s);
if ($v > 0) {
$m = $l + $l - $v;
$sv = ($v - $m) / $v;
$h *= 6.0;
$sextant = floor($h);
$fract = $h - $sextant;
$vsf = $v * $sv * $fract;
$mid1 = $m + $vsf;
$mid2 = $v - $vsf;

switch ($sextant) {
case 0:
$red = $v;
$green = $mid1;
$blue = $m;
break;
case 1:
$red = $mid2;
$green = $v;
$blue = $m;
break;
case 2:
$red = $m;
$green = $v;
$blue = $mid1;
break;
case 3:
$red = $m;
$green = $mid2;
$blue = $v;
break;
case 4:
$red = $mid1;
$green = $m;
$blue = $v;
break;
case 5:
$red = $v;
$green = $m;
$blue = $mid2;
break;
}
}

$red = round($red * 255, 0);
$green = round($green * 255, 0);
$blue = round($blue * 255, 0);

if ($toHex) {
$red = ($red < 15) ? '0'.dechex($red) : dechex($red);
$green = ($green < 15) ? '0'.dechex($green) : dechex($green);
$blue = ($blue < 15) ? '0'.dechex($blue) : dechex($blue);

return "#{$red}{$green}{$blue}";
} else {
return ['red' => $red, 'green' => $green, 'blue' => $blue];
}
}

/**
* Get contrasting foreground color for autoColor background.
*/
protected function getContrastColor($hexColor)
{
// hexColor RGB
$R1 = hexdec(substr($hexColor, 1, 2));
$G1 = hexdec(substr($hexColor, 3, 2));
$B1 = hexdec(substr($hexColor, 5, 2));

// Black RGB
$blackColor = '#000000';
$R2BlackColor = hexdec(substr($blackColor, 1, 2));
$G2BlackColor = hexdec(substr($blackColor, 3, 2));
$B2BlackColor = hexdec(substr($blackColor, 5, 2));

// Calc contrast ratio
$L1 = 0.2126 * pow($R1 / 255, 2.2) +
0.7152 * pow($G1 / 255, 2.2) +
0.0722 * pow($B1 / 255, 2.2);

$L2 = 0.2126 * pow($R2BlackColor / 255, 2.2) +
0.7152 * pow($G2BlackColor / 255, 2.2) +
0.0722 * pow($B2BlackColor / 255, 2.2);

$contrastRatio = 0;
if ($L1 > $L2) {
$contrastRatio = (int) (($L1 + 0.05) / ($L2 + 0.05));
} else {
$contrastRatio = (int) (($L2 + 0.05) / ($L1 + 0.05));
}

// If contrast is more than 5, return black color
if ($contrastRatio > 5) {
return '#000000';
} else {
// if not, return white color.
return '#FFFFFF';
}
}
}
29 changes: 29 additions & 0 deletions tests/AutoColorUtilsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use LasseRafn\InitialAvatarGenerator\InitialAvatar;
use PHPUnit\Framework\TestCase;

class AutoColorUtilsTest extends TestCase
{
/** @test */
public function can_create_all_colors()
{
$avatar = new InitialAvatar();

$avatar->name('A')->autoColor();
$this->assertEquals('#f0a742', $avatar->getBackgroundColor());
$this->assertEquals('#000000', $avatar->getColor());

$avatar->name('B')->autoColor();
$this->assertEquals('#42caf0', $avatar->getBackgroundColor());
$this->assertEquals('#000000', $avatar->getColor());

$avatar->name('C')->autoColor();
$this->assertEquals('#42f085', $avatar->getBackgroundColor());
$this->assertEquals('#000000', $avatar->getColor());

$avatar->name('D')->autoColor();
$this->assertEquals('#f04293', $avatar->getBackgroundColor());
$this->assertEquals('#FFFFFF', $avatar->getColor());
}
}
12 changes: 12 additions & 0 deletions tests/ParameterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,16 @@ public function can_set_auto_font()

$this->assertNotTrue($avatar->getAutoFont());
}

/** @test */
public function can_set_auto_color()
{
$avatar = new InitialAvatar();

$avatar->autoColor();

$this->assertEquals('#eaf042', $avatar->getBackgroundColor());

$this->assertEquals('#000000', $avatar->getColor());
}
}