Subversion Repositories php_utils

Rev

Rev 57 | 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
86 daniel-mar 6
 * Revision 2023-08-29
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) {
86 daniel-mar 108
 
109
        $i = 0;
110
        do {
111
                $i++;
112
                $dummy = "[$i]";
113
        } while (strpos($css_content, $dummy) !== false);
114
 
115
        $css_content = preg_replace('@(\\}\\s*)#@ismU', '\\1'.$dummy, $css_content);
116
        $css_content = preg_replace('@(^\\s*)#@isU', '\\1'.$dummy, $css_content);
54 daniel-mar 117
        $css_content = preg_replace_callback('@#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})@ismU',
57 daniel-mar 118
                function ($x) use ($rgb_function) {
54 daniel-mar 119
                        if (strlen($x[1]) == 3) {
120
                                $r = hexdec($x[1][0].$x[1][0]);
121
                                $g = hexdec($x[1][1].$x[1][1]);
122
                                $b = hexdec($x[1][2].$x[1][2]);
6 daniel-mar 123
                        } else {
54 daniel-mar 124
                                $r = hexdec($x[1][0].$x[1][1]);
125
                                $g = hexdec($x[1][2].$x[1][3]);
126
                                $b = hexdec($x[1][4].$x[1][5]);
6 daniel-mar 127
                        }
57 daniel-mar 128
                        $rgb_function($r,$g,$b);
54 daniel-mar 129
                        return rgb2html($r,$g,$b);
6 daniel-mar 130
                }, $css_content);
57 daniel-mar 131
        $css_content = preg_replace_callback('@rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)@ismU',
132
                function ($x) use ($rgb_function) {
133
                        $r = $x[1];
134
                        $g = $x[2];
135
                        $b = $x[3];
136
                        $rgb_function($r,$g,$b);
137
                        return "rgb($r,$g,$b)";
138
                }, $css_content);
139
        $css_content = preg_replace_callback('@rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([\\d\\.]+)\\s*\\)@ismU',
140
                function ($x) use ($rgb_function) {
141
                        $r = $x[1];
142
                        $g = $x[2];
143
                        $b = $x[3];
144
                        $a = $x[4];
145
                        $rgb_function($r,$g,$b);
146
                        return "rgba($r,$g,$b,$a)";
147
                }, $css_content);
148
        $css_content = preg_replace_callback('@\\-rgb:\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*;@ismU',
149
                // Bootstrap uses "--bs-link-color-rgb: 13,110,253;" which we must also accept
150
                function ($x) use ($rgb_function) {
151
                        $r = $x[1];
152
                        $g = $x[2];
153
                        $b = $x[3];
154
                        $rgb_function($r,$g,$b);
155
                        return "-rgb:$r,$g,$b;";
156
                }, $css_content);
86 daniel-mar 157
        $css_content = str_replace($dummy, '#', $css_content);
158
        return $css_content;
6 daniel-mar 159
}
160
 
57 daniel-mar 161
function changeHueOfCSS($css_content, $h_shift=0, $s_shift=0, $v_shift=0) {
162
        $rgb_function = function(&$r,&$g,&$b) use ($h_shift, $s_shift, $v_shift) {
163
                list ($h,$s,$v) = RGB_TO_HSV($r, $g, $b);
164
                $h = (float)$h;
165
                $s = (float)$s;
166
                $v = (float)$v;
167
                $h = ($h + $h_shift); while ($h > 1) $h -= 1; while ($h < 0) $h += 1;
168
                $s = ($s + $s_shift); while ($s > 1) $s  = 1; while ($s < 0) $s  = 0;
169
                $v = ($v + $v_shift); while ($v > 1) $v  = 1; while ($v < 0) $v  = 0;
170
                list ($r,$g,$b) = HSV_TO_RGB($h, $s, $v);
171
        };
172
        return changeCSSWithRgbFunction($css_content, $rgb_function);
173
}
174
 
6 daniel-mar 175
function invertColorsOfCSS($css_content) {
57 daniel-mar 176
        $rgb_function = function(&$r,&$g,&$b) {
177
                $r = 255 - $r;
178
                $g = 255 - $g;
179
                $b = 255 - $b;
180
        };
181
        return changeCSSWithRgbFunction($css_content, $rgb_function);
6 daniel-mar 182
}