Subversion Repositories php_utils

Rev

Rev 57 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * Color Utils for PHP
  5.  * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
  6.  * Revision 2023-08-29
  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.  
  106. // TODO: Also support hsl() and hsla() color schemes
  107. function changeCSSWithRgbFunction($css_content, $rgb_function) {
  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);
  117.         $css_content = preg_replace_callback('@#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})@ismU',
  118.                 function ($x) use ($rgb_function) {
  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]);
  123.                         } else {
  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]);
  127.                         }
  128.                         $rgb_function($r,$g,$b);
  129.                         return rgb2html($r,$g,$b);
  130.                 }, $css_content);
  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);
  157.         $css_content = str_replace($dummy, '#', $css_content);
  158.         return $css_content;
  159. }
  160.  
  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.  
  175. function invertColorsOfCSS($css_content) {
  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);
  182. }
  183.