Skip to content

Commit 18d22b7

Browse files
author
stil
committed
Add methods toArray(), parseString(), fromHsl() to Color class
1 parent 34f87b2 commit 18d22b7

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

src/Color.php

+76
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<?php
22
namespace GDText;
33

4+
/**
5+
* 8-bit RGB color representation.
6+
* @package GDText
7+
*/
48
class Color
59
{
610
/**
@@ -37,6 +41,70 @@ public function __construct($red = 0, $green = 0, $blue = 0, $alpha = null)
3741
$this->alpha = $alpha;
3842
}
3943

44+
/**
45+
* Parses string to Color object representation.
46+
* @param string $str String with color information, ex. #000000
47+
* @return Color
48+
* @todo Add parsing of CSS-like strings: rgb(), rgba(), hsl()
49+
*/
50+
public static function parseString($str)
51+
{
52+
$str = str_replace('#', '', $str);
53+
if (strlen($str) == 6) {
54+
$r = hexdec(substr($str, 0, 2));
55+
$g = hexdec(substr($str, 2, 2));
56+
$b = hexdec(substr($str, 4, 2));
57+
} else if (strlen($str) == 3) {
58+
$r = hexdec(str_repeat(substr($str, 0, 1), 2));
59+
$g = hexdec(str_repeat(substr($str, 1, 1), 2));
60+
$b = hexdec(str_repeat(substr($str, 2, 1), 2));
61+
} else {
62+
throw new \InvalidArgumentException('Unrecognized color.');
63+
}
64+
65+
return new Color($r, $g, $b);
66+
}
67+
68+
/**
69+
* @param float $h Hue
70+
* @param float $s Saturation
71+
* @param float $l Light
72+
* @return Color
73+
*/
74+
public static function fromHsl($h, $s, $l)
75+
{
76+
$fromFloat = function (array $rgb) {
77+
foreach ($rgb as &$v) {
78+
$v = (int)round($v * 255);
79+
};
80+
81+
return new Color($rgb[0], $rgb[1], $rgb[2]);
82+
};
83+
84+
// If saturation is 0, the given color is grey and only
85+
// lightness is relevant.
86+
if ($s == 0) {
87+
return $fromFloat(array($l, $l, $l));
88+
}
89+
90+
// Else calculate r, g, b according to hue.
91+
// Check http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL for details
92+
$chroma = (1 - abs(2 * $l - 1)) * $s;
93+
$h_ = $h * 6;
94+
$x = $chroma * (1 - abs((fmod($h_,2)) - 1)); // Note: fmod because % (modulo) returns int value!!
95+
$m = $l - round($chroma/2, 10); // Bugfix for strange float behaviour (e.g. $l=0.17 and $s=1)
96+
97+
if ($h_ >= 0 && $h_ < 1) $rgb = array(($chroma + $m), ($x + $m), $m);
98+
elseif ($h_ >= 1 && $h_ < 2) $rgb = array(($x + $m), ($chroma + $m), $m);
99+
elseif ($h_ >= 2 && $h_ < 3) $rgb = array($m, ($chroma + $m), ($x + $m));
100+
elseif ($h_ >= 3 && $h_ < 4) $rgb = array($m, ($x + $m), ($chroma + $m));
101+
elseif ($h_ >= 4 && $h_ < 5) $rgb = array(($x + $m), $m, ($chroma + $m));
102+
elseif ($h_ >= 5 && $h_ < 6) $rgb = array(($chroma + $m), $m, ($x + $m));
103+
else throw new \InvalidArgumentException('Invalid hue, it should be a value between 0 and 1.');
104+
105+
return $fromFloat($rgb);
106+
}
107+
40108
/**
41109
* @param resource $image GD image resource
42110
* @return int Returns the index of the specified color+alpha in the palette of the image,
@@ -68,4 +136,12 @@ public function hasAlphaChannel()
68136
{
69137
return $this->alpha !== null;
70138
}
139+
140+
/**
141+
* @return int[]
142+
*/
143+
public function toArray()
144+
{
145+
return array($this->red, $this->green, $this->blue);
146+
}
71147
}

tests/ColorTest.php

+41
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,45 @@ public function testTrueColorImage()
2929
$index = $color->getIndex($im);
3030
$this->assertNotEquals(-1, $index);
3131
}
32+
33+
public function testToArray()
34+
{
35+
$color = new Color(12, 34, 56);
36+
$this->assertEquals(array(12, 34, 56), $color->toArray());
37+
}
38+
39+
public function testFromHsl()
40+
{
41+
$table = [
42+
[[0.5, 0.8, 0.3], [15, 138, 138]],
43+
[[0.999, 1, 1], [255, 255, 255]],
44+
[[0, 0, 0], [0, 0, 0]],
45+
[[338/360, 0.85, 0.25], [118, 10, 49]],
46+
];
47+
48+
foreach ($table as $pair) {
49+
list($hsl, $rgb) = $pair;
50+
$color = Color::fromHsl($hsl[0], $hsl[1], $hsl[2]);
51+
52+
$this->assertEquals($rgb, $color->toArray());
53+
}
54+
}
55+
56+
public function testParseString()
57+
{
58+
$table = [
59+
['#000', [0, 0, 0]],
60+
['#fff', [255, 255, 255]],
61+
['#abcdef', [171, 205, 239]],
62+
['#FEDCBA', [254, 220, 186]],
63+
['FEDCBA', [254, 220, 186]],
64+
['#abc', [170, 187, 204]],
65+
['abc', [170, 187, 204]],
66+
];
67+
68+
foreach ($table as $pair) {
69+
$color = Color::parseString($pair[0]);
70+
$this->assertEquals($pair[1], $color->toArray());
71+
}
72+
}
3273
}

0 commit comments

Comments
 (0)