1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
|
4
|
|
|
namespace projectcleverweb\color; |
5
|
|
|
|
6
|
|
|
|
7
|
|
|
class generate { |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Convert a hex string (no #) to a RGB array |
11
|
|
|
* |
12
|
|
|
* @param string $hex The hex string to convert (no #) |
13
|
|
|
* @return array The RGB array |
14
|
|
|
*/ |
15
|
1 |
|
public static function hex_to_rgb(string $hex) :array { |
16
|
|
|
return [ |
17
|
1 |
|
'r' => hexdec(substr($hex, 0, 2)), |
18
|
1 |
|
'g' => hexdec(substr($hex, 2, 2)), |
19
|
1 |
|
'b' => hexdec(substr($hex, 4, 2)) |
20
|
|
|
]; |
21
|
|
|
} |
22
|
|
|
|
23
|
1 |
|
public static function rgb_to_hex(int $r, int $g, int $b) :string { |
24
|
1 |
|
return strtoupper( |
25
|
1 |
|
str_pad(dechex($r), 2, '0', STR_PAD_LEFT) |
26
|
1 |
|
.str_pad(dechex($g), 2, '0', STR_PAD_LEFT) |
27
|
1 |
|
.str_pad(dechex($b), 2, '0', STR_PAD_LEFT) |
28
|
|
|
); |
29
|
|
|
} |
30
|
|
|
|
31
|
1 |
|
public static function rgb_to_cmyk(float $r, float $g, float $b) :array { |
32
|
1 |
|
$c = (255 - $r) / 255 * 100; |
33
|
1 |
|
$m = (255 - $g) / 255 * 100; |
34
|
1 |
|
$y = (255 - $b) / 255 * 100; |
35
|
1 |
|
$k = min(array($c,$m,$y)); |
36
|
1 |
|
$c -= $k; |
37
|
1 |
|
$m -= $k; |
38
|
1 |
|
$y -= $k; |
39
|
|
|
return [ |
40
|
1 |
|
'c' => round($c), |
41
|
1 |
|
'm' => round($m), |
42
|
1 |
|
'y' => round($y), |
43
|
1 |
|
'k' => round($k) |
44
|
|
|
]; |
45
|
|
|
} |
46
|
|
|
|
47
|
1 |
|
public static function cmyk_to_rgb(float $c, float $m, float $y, float $k) :array { |
48
|
1 |
|
$c /= 100; |
49
|
1 |
|
$m /= 100; |
50
|
1 |
|
$y /= 100; |
51
|
1 |
|
$k /= 100; |
52
|
1 |
|
$r = 1 - min(1, $c * (1 - $k) + $k); |
53
|
1 |
|
$g = 1 - min(1, $m * (1 - $k) + $k); |
54
|
1 |
|
$b = 1 - min(1, $y * (1 - $k) + $k); |
55
|
|
|
return [ |
56
|
1 |
|
'r' => round($r * 255), |
57
|
1 |
|
'g' => round($g * 255), |
58
|
1 |
|
'b' => round($b * 255) |
59
|
|
|
]; |
60
|
|
|
} |
61
|
|
|
|
62
|
1 |
|
public static function rgb_contrast(int $r = 0, int $g = 0, int $b = 0) :array { |
63
|
|
|
return [ |
64
|
1 |
|
'r' => ($r < 128) ? 255 : 0, |
65
|
1 |
|
'g' => ($g < 128) ? 255 : 0, |
66
|
1 |
|
'b' => ($b < 128) ? 255 : 0 |
67
|
|
|
]; |
68
|
|
|
} |
69
|
|
|
|
70
|
1 |
|
public static function rgb_invert(int $r = 0, int $g = 0, int $b = 0) :array { |
71
|
|
|
return [ |
72
|
1 |
|
'r' => 255 - $r, |
73
|
1 |
|
'g' => 255 - $g, |
74
|
1 |
|
'b' => 255 - $b |
75
|
|
|
]; |
76
|
|
|
} |
77
|
|
|
|
78
|
2 |
|
public static function yiq_score(int $r = 0, int $g = 0, int $b = 0) :float { |
79
|
2 |
|
return (($r * 299) + ($g * 587) + ($b * 114)) / 1000; |
80
|
|
|
} |
81
|
|
|
|
82
|
1 |
|
public static function rand(int $min_r = 0, int $max_r = 255, int $min_g = 0, int $max_g = 255, int $min_b = 0, int $max_b = 255) :array { |
83
|
|
|
return [ |
84
|
1 |
|
'r' => rand(abs((int) $min_r) % 256, abs((int) $max_r) % 256), |
85
|
1 |
|
'g' => rand(abs((int) $min_g) % 256, abs((int) $max_g) % 256), |
86
|
1 |
|
'b' => rand(abs((int) $min_b) % 256, abs((int) $max_b) % 256) |
87
|
|
|
]; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
|
91
|
2 |
|
public static function rgb_to_hsl(int $r = 0, int $g = 0, int $b = 0, $accuracy = 2) :array { |
92
|
2 |
|
$r /= 255; |
93
|
2 |
|
$g /= 255; |
94
|
2 |
|
$b /= 255; |
95
|
2 |
|
$min = min($r, $g, $b); |
96
|
2 |
|
$max = max($r, $g, $b); |
97
|
2 |
|
$delta = $max - $min; |
98
|
2 |
|
$h = 0; |
99
|
2 |
|
$s = 0; |
100
|
2 |
|
$l = ($max + $min) / 2; |
101
|
|
|
|
102
|
2 |
|
if ($delta != 0) { |
103
|
2 |
|
$s = $delta / ($max + $min); |
104
|
2 |
|
if ($l >= 0.5) { |
105
|
2 |
|
$s = $delta / (2 - $max - $min); |
106
|
|
|
} |
107
|
2 |
|
static::_rgbhsl_hue($h, $r, $g, $b, $max, $delta); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
return [ |
111
|
2 |
|
'h' => round($h * 360, $accuracy), |
112
|
2 |
|
's' => round($s * 100, $accuracy), |
113
|
2 |
|
'l' => round($l * 100, $accuracy) |
114
|
|
|
]; |
115
|
|
|
} |
116
|
|
|
|
117
|
2 |
|
protected static function _rgbhsl_delta_rgb(float $rgb, float $max, float $delta) { |
118
|
2 |
|
return ((($max - $rgb) / 6) + ($delta / 2)) / $delta; |
119
|
|
|
} |
120
|
|
|
|
121
|
2 |
|
protected static function _rgbhsl_hue(float &$h, float $r, float $g, float $b, float $max, float $delta) { |
122
|
2 |
|
$delta_r = static::_rgbhsl_delta_rgb($r, $max, $delta); |
123
|
2 |
|
$delta_g = static::_rgbhsl_delta_rgb($g, $max, $delta); |
124
|
2 |
|
$delta_b = static::_rgbhsl_delta_rgb($b, $max, $delta); |
125
|
|
|
|
126
|
2 |
|
$h = (2 / 3) + $delta_g - $delta_r; |
127
|
2 |
|
if ($r == $max) { |
128
|
2 |
|
$h = $delta_b - $delta_g; |
129
|
2 |
|
} elseif ($g == $max) { |
130
|
2 |
|
$h = (1 / 3) + $delta_r - $delta_b; |
131
|
|
|
} |
132
|
2 |
|
if ($h < 0) { |
133
|
2 |
|
$h++; |
134
|
|
|
} |
135
|
2 |
|
} |
136
|
|
|
|
137
|
2 |
|
public static function hsl_to_rgb(float $h = 0, float $s = 0, float $l = 0) :array { |
138
|
2 |
|
$s /= 100; |
139
|
2 |
|
$l /= 100; |
140
|
2 |
|
$c = (1 - abs((2 * $l) - 1)) * $s; |
141
|
2 |
|
$x = $c * (1 - abs(fmod(($h / 60), 2) - 1)); |
142
|
2 |
|
$m = $l - ($c / 2); |
143
|
2 |
|
$r = $c; |
144
|
2 |
|
$g = 0; |
145
|
2 |
|
$b = $x; |
146
|
|
|
|
147
|
2 |
|
if ($h < 180) { |
148
|
2 |
|
self::_hslrgb_low($r, $g, $b, $c, $x, $h); |
149
|
2 |
|
} elseif ($h < 300) { |
150
|
2 |
|
self::_hslrgb_high($r, $g, $b, $c, $x, $h); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
return [ |
154
|
2 |
|
'r' => (int) round(($r + $m) * 255), |
155
|
2 |
|
'g' => (int) round(($g + $m) * 255), |
156
|
2 |
|
'b' => (int) round(($b + $m) * 255) |
157
|
|
|
]; |
158
|
|
|
} |
159
|
|
|
|
160
|
2 |
|
private static function _hslrgb_low(float &$r, float &$g, float &$b, float $c, float $x, float $h) { |
161
|
2 |
|
if ($h < 60) { |
162
|
2 |
|
$r = $c; |
163
|
2 |
|
$g = $x; |
164
|
2 |
|
$b = 0; |
165
|
2 |
|
} elseif ($h < 120) { |
166
|
2 |
|
$r = $x; |
167
|
2 |
|
$g = $c; |
168
|
2 |
|
$b = 0; |
169
|
2 |
|
} elseif ($h < 180) { |
170
|
2 |
|
$r = 0; |
171
|
2 |
|
$g = $c; |
172
|
2 |
|
$b = $x; |
173
|
|
|
} |
174
|
2 |
|
} |
175
|
|
|
|
176
|
2 |
|
private static function _hslrgb_high(float &$r, float &$g, float &$b, float $c, float $x, float $h) { |
177
|
2 |
|
if ($h < 240) { |
178
|
2 |
|
$r = 0; |
179
|
2 |
|
$g = $x; |
180
|
2 |
|
$b = $c; |
181
|
2 |
|
} elseif ($h < 300) { |
182
|
2 |
|
$r = $x; |
183
|
2 |
|
$g = 0; |
184
|
2 |
|
$b = $c; |
185
|
|
|
} |
186
|
2 |
|
} |
187
|
|
|
|
188
|
1 |
|
public static function rgb_to_hsb(float $r, float $g, float $b, int $accuracy = 3) { |
189
|
1 |
|
$r /= 255; |
190
|
1 |
|
$g /= 255; |
191
|
1 |
|
$b /= 255; |
192
|
|
|
|
193
|
1 |
|
$max = max($r, $g, $b); |
194
|
1 |
|
$min = min($r, $g, $b); |
195
|
1 |
|
$v = $max; |
|
|
|
|
196
|
|
|
|
197
|
1 |
|
$d = $max - $min; |
198
|
1 |
|
$s = $max == 0 ? 0 : $d / $max; |
199
|
|
|
|
200
|
1 |
|
$h = 0; // achromatic |
201
|
1 |
|
if ($max !== $min) { |
202
|
|
|
switch ($max) { |
203
|
1 |
|
case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break; |
|
|
|
|
204
|
1 |
|
case $g: $h = ($b - $r) / $d + 2; break; |
|
|
|
|
205
|
1 |
|
case $b: $h = ($r - $g) / $d + 4; break; |
|
|
|
|
206
|
|
|
} |
207
|
1 |
|
$h /= 6; |
208
|
|
|
} |
209
|
|
|
// map top 360,100,100 |
|
|
|
|
210
|
1 |
|
$h = round($h * 360, $accuracy); |
211
|
1 |
|
$s = round($s * 100, $accuracy); |
212
|
1 |
|
$v = round($v * 100, $accuracy); |
213
|
|
|
|
214
|
1 |
|
return ['h' => $h, 's' => $s, 'b' => $v]; |
215
|
|
|
} |
216
|
|
|
|
217
|
1 |
|
public static function hsb_to_rgb(float $h, float $s, float $v, int $accuracy = 3) { |
218
|
|
|
// $h = $h / 360; |
|
|
|
|
219
|
1 |
|
if ($v == 0) { |
220
|
1 |
|
return ['r' => 0, 'g' => 0, 'b' => 0]; |
221
|
|
|
} |
222
|
|
|
|
223
|
1 |
|
$s = $s / 100; |
224
|
1 |
|
$v = $v / 100; |
225
|
1 |
|
$h = $h / 60; |
226
|
|
|
|
227
|
1 |
|
$i = floor($h); |
228
|
1 |
|
$f = $h - $i; |
229
|
1 |
|
$p = $v * (1 - $s); |
230
|
1 |
|
$q = $v * (1 - ($s * $f)); |
231
|
1 |
|
$t = $v * (1 - ($s * (1 - $f))); |
232
|
1 |
|
if ($i == 0) { |
233
|
1 |
|
$r = $v; $g = $t; $b = $p; |
|
|
|
|
234
|
1 |
|
} elseif ($i == 1) { |
235
|
1 |
|
$r = $q; $g = $v; $b = $p; |
|
|
|
|
236
|
1 |
|
} elseif ($i == 2) { |
237
|
1 |
|
$r = $p; $g = $v; $b = $t; |
|
|
|
|
238
|
1 |
|
} elseif ($i == 3) { |
239
|
1 |
|
$r = $p; $g = $q; $b = $v; |
|
|
|
|
240
|
1 |
|
} elseif ($i == 4) { |
241
|
1 |
|
$r = $t; $g = $p; $b = $v; |
|
|
|
|
242
|
1 |
|
} elseif ($i == 5) { |
243
|
1 |
|
$r = $v; $g = $p; $b = $q; |
|
|
|
|
244
|
|
|
} |
245
|
|
|
|
246
|
1 |
|
$r = round($r * 255, $accuracy); |
|
|
|
|
247
|
1 |
|
$g = round($g * 255, $accuracy); |
|
|
|
|
248
|
1 |
|
$b = round($b * 255, $accuracy); |
|
|
|
|
249
|
|
|
|
250
|
1 |
|
return ['r' => $r, 'g' => $g, 'b' => $b]; |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
|
254
|
|
|
|
255
|
|
|
|
256
|
|
|
|
257
|
|
|
} |
258
|
|
|
|
This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.
To visualize
will produce issues in the first and second line, while this second example
will produce no issues.