Rev 54 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
53 | daniel-mar | 4 | * Color Utils for PHP |
57 | daniel-mar | 5 | * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft |
6 | * Revision 2023-01-03 |
||
6 | daniel-mar | 7 | * |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
9 | * you may not use this file except in compliance with the License. |
||
10 | * You may obtain a copy of the License at |
||
11 | * |
||
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
13 | * |
||
14 | * Unless required by applicable law or agreed to in writing, software |
||
15 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
17 | * See the License for the specific language governing permissions and |
||
18 | * limitations under the License. |
||
19 | */ |
||
20 | |||
21 | // Some of these functions were taken from other sources. |
||
22 | |||
23 | function RGB_TO_HSV($R, $G, $B) { // RGB Values:Number 0-255 |
||
24 | // HSV Results:Number 0-1 |
||
25 | $HSL = array(); |
||
26 | |||
27 | $var_R = ($R / 255); |
||
28 | $var_G = ($G / 255); |
||
29 | $var_B = ($B / 255); |
||
30 | |||
31 | $var_Min = min($var_R, $var_G, $var_B); |
||
32 | $var_Max = max($var_R, $var_G, $var_B); |
||
33 | $del_Max = $var_Max - $var_Min; |
||
34 | |||
35 | $V = $var_Max; |
||
36 | |||
37 | if ($del_Max == 0) { |
||
38 | $H = 0; |
||
39 | $S = 0; |
||
40 | } else { |
||
41 | $S = $del_Max / $var_Max; |
||
42 | |||
43 | $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max; |
||
44 | $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max; |
||
45 | $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max; |
||
46 | |||
47 | if ($var_R == $var_Max) $H = $del_B - $del_G; |
||
48 | else if ($var_G == $var_Max) $H = (1/3) + $del_R - $del_B; |
||
49 | else if ($var_B == $var_Max) $H = (2/3) + $del_G - $del_R; |
||
50 | else $H = 0; |
||
51 | |||
52 | if ($H<0) $H++; |
||
53 | if ($H>1) $H--; |
||
54 | } |
||
55 | |||
56 | return array($H, $S, $V); |
||
57 | } |
||
58 | |||
59 | function HSV_TO_RGB($H, $S, $V) { // HSV Values:Number 0-1 |
||
60 | // RGB Results:Number 0-255 |
||
61 | $RGB = array(); |
||
62 | |||
63 | if($S == 0) { |
||
64 | $R = $G = $B = $V * 255; |
||
65 | } else { |
||
66 | $var_H = $H * 6; |
||
67 | $var_i = floor( $var_H ); |
||
68 | $var_1 = $V * ( 1 - $S ); |
||
69 | $var_2 = $V * ( 1 - $S * ( $var_H - $var_i )); |
||
70 | $var_3 = $V * ( 1 - $S * (1 - ($var_H - $var_i ))); |
||
71 | |||
72 | if ($var_i == 0) { $var_R = $V ; $var_G = $var_3 ; $var_B = $var_1 ; } |
||
73 | else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $V ; $var_B = $var_1 ; } |
||
74 | else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $V ; $var_B = $var_3 ; } |
||
75 | else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $V ; } |
||
76 | else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $V ; } |
||
77 | else { $var_R = $V ; $var_G = $var_1 ; $var_B = $var_2 ; } |
||
78 | |||
79 | $R = $var_R * 255; |
||
80 | $G = $var_G * 255; |
||
81 | $B = $var_B * 255; |
||
82 | } |
||
83 | |||
84 | return array($R, $G, $B); |
||
85 | } |
||
86 | |||
87 | function rgb2html($r, $g=-1, $b=-1) { |
||
88 | if (is_array($r) && sizeof($r) == 3) { |
||
89 | list($r, $g, $b) = $r; |
||
90 | } |
||
91 | |||
92 | $r = intval($r); |
||
93 | $g = intval($g); |
||
94 | $b = intval($b); |
||
95 | |||
96 | $r = dechex($r<0 ? 0 : ($r>255 ? 255 : $r)); |
||
97 | $g = dechex($g<0 ? 0 : ($g>255 ? 255 : $g)); |
||
98 | $b = dechex($b<0 ? 0 : ($b>255 ? 255 : $b)); |
||
99 | |||
100 | $color = (strlen($r) < 2 ? '0' : '').$r; |
||
101 | $color .= (strlen($g) < 2 ? '0' : '').$g; |
||
102 | $color .= (strlen($b) < 2 ? '0' : '').$b; |
||
103 | return '#'.$color; |
||
104 | } |
||
105 | |||
57 | daniel-mar | 106 | // TODO: Also support hsl() and hsla() color schemes |
107 | function changeCSSWithRgbFunction($css_content, $rgb_function) { |
||
54 | daniel-mar | 108 | $css_content = preg_replace('@(\\}\\s*)#@ismU', '\\1'.chr(1), $css_content); |
109 | $css_content = preg_replace('@(^\\s*)#@isU', '\\1'.chr(1), $css_content); |
||
110 | $css_content = preg_replace_callback('@#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})@ismU', |
||
57 | daniel-mar | 111 | function ($x) use ($rgb_function) { |
54 | daniel-mar | 112 | if (strlen($x[1]) == 3) { |
113 | $r = hexdec($x[1][0].$x[1][0]); |
||
114 | $g = hexdec($x[1][1].$x[1][1]); |
||
115 | $b = hexdec($x[1][2].$x[1][2]); |
||
6 | daniel-mar | 116 | } else { |
54 | daniel-mar | 117 | $r = hexdec($x[1][0].$x[1][1]); |
118 | $g = hexdec($x[1][2].$x[1][3]); |
||
119 | $b = hexdec($x[1][4].$x[1][5]); |
||
6 | daniel-mar | 120 | } |
57 | daniel-mar | 121 | $rgb_function($r,$g,$b); |
54 | daniel-mar | 122 | return rgb2html($r,$g,$b); |
6 | daniel-mar | 123 | }, $css_content); |
57 | daniel-mar | 124 | $css_content = preg_replace_callback('@rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)@ismU', |
125 | function ($x) use ($rgb_function) { |
||
126 | $r = $x[1]; |
||
127 | $g = $x[2]; |
||
128 | $b = $x[3]; |
||
129 | $rgb_function($r,$g,$b); |
||
130 | return "rgb($r,$g,$b)"; |
||
131 | }, $css_content); |
||
132 | $css_content = preg_replace_callback('@rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([\\d\\.]+)\\s*\\)@ismU', |
||
133 | function ($x) use ($rgb_function) { |
||
134 | $r = $x[1]; |
||
135 | $g = $x[2]; |
||
136 | $b = $x[3]; |
||
137 | $a = $x[4]; |
||
138 | $rgb_function($r,$g,$b); |
||
139 | return "rgba($r,$g,$b,$a)"; |
||
140 | }, $css_content); |
||
141 | $css_content = preg_replace_callback('@\\-rgb:\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*;@ismU', |
||
142 | // Bootstrap uses "--bs-link-color-rgb: 13,110,253;" which we must also accept |
||
143 | function ($x) use ($rgb_function) { |
||
144 | $r = $x[1]; |
||
145 | $g = $x[2]; |
||
146 | $b = $x[3]; |
||
147 | $rgb_function($r,$g,$b); |
||
148 | return "-rgb:$r,$g,$b;"; |
||
149 | }, $css_content); |
||
54 | daniel-mar | 150 | $css_content = str_replace(chr(1), '#', $css_content); |
6 | daniel-mar | 151 | return $css_content; |
152 | } |
||
153 | |||
57 | daniel-mar | 154 | function changeHueOfCSS($css_content, $h_shift=0, $s_shift=0, $v_shift=0) { |
155 | $rgb_function = function(&$r,&$g,&$b) use ($h_shift, $s_shift, $v_shift) { |
||
156 | list ($h,$s,$v) = RGB_TO_HSV($r, $g, $b); |
||
157 | $h = (float)$h; |
||
158 | $s = (float)$s; |
||
159 | $v = (float)$v; |
||
160 | $h = ($h + $h_shift); while ($h > 1) $h -= 1; while ($h < 0) $h += 1; |
||
161 | $s = ($s + $s_shift); while ($s > 1) $s = 1; while ($s < 0) $s = 0; |
||
162 | $v = ($v + $v_shift); while ($v > 1) $v = 1; while ($v < 0) $v = 0; |
||
163 | list ($r,$g,$b) = HSV_TO_RGB($h, $s, $v); |
||
164 | }; |
||
165 | return changeCSSWithRgbFunction($css_content, $rgb_function); |
||
166 | } |
||
167 | |||
6 | daniel-mar | 168 | function invertColorsOfCSS($css_content) { |
57 | daniel-mar | 169 | $rgb_function = function(&$r,&$g,&$b) { |
170 | $r = 255 - $r; |
||
171 | $g = 255 - $g; |
||
172 | $b = 255 - $b; |
||
173 | }; |
||
174 | return changeCSSWithRgbFunction($css_content, $rgb_function); |
||
6 | daniel-mar | 175 | } |