有人知道如何在 PHP 中将十六进制颜色转换为 HSL 吗?我已经搜索过,但我发现的函数不能精确转换颜色。
我认为第二个答案中的错误是在红色为最大颜色值时计算色调时使用整数除法而不是 fmod()
$hue = (($green - $blue) / $delta) % 6;
我认为第一个答案中的错误在于饱和度计算中 - 对我来说
$s = $l > 0.5 ? $diff / (2 - $max - $min) : $diff / ($max + $min);
拆开有点混乱
由于通常当我想将 RGB 转换为 HSL 时,我想调整亮度值以制作相同颜色的较浅或较暗版本,因此我通过添加可选的 $ladj 百分比值将其构建到下面的函数中。
$hex 参数可以是十六进制字符串(带或不带“#”)或 RGB 值数组(0 到 255 之间)
返回值是一个 HSL 字符串,可以直接放入 CSS 颜色中。即色调的值从 0 到 359,饱和度和亮度的值从 0 到 100%。
我认为这工作正常(基于https://gist.github.com/brandonheyer/5254516)
function hex2hsl($RGB, $ladj = 0) {
//have we got an RGB array or a string of hex RGB values (assume it is valid!)
if (!is_array($RGB)) {
$hexstr = ltrim($RGB, '#');
if (strlen($hexstr) == 3) {
$hexstr = $hexstr[0] . $hexstr[0] . $hexstr[1] . $hexstr[1] . $hexstr[2] . $hexstr[2];
}
$R = hexdec($hexstr[0] . $hexstr[1]);
$G = hexdec($hexstr[2] . $hexstr[3]);
$B = hexdec($hexstr[4] . $hexstr[5]);
$RGB = array($R,$G,$B);
}
// scale the RGB values to 0 to 1 (percentages)
$r = $RGB[0]/255;
$g = $RGB[1]/255;
$b = $RGB[2]/255;
$max = max( $r, $g, $b );
$min = min( $r, $g, $b );
// lightness calculation. 0 to 1 value, scale to 0 to 100% at end
$l = ( $max + $min ) / 2;
// saturation calculation. Also 0 to 1, scale to percent at end.
$d = $max - $min;
if( $d == 0 ){
// achromatic (grey) so hue and saturation both zero
$h = $s = 0;
} else {
$s = $d / ( 1 - abs( (2 * $l) - 1 ) );
// hue (if not grey) This is being calculated directly in degrees (0 to 360)
switch( $max ){
case $r:
$h = 60 * fmod( ( ( $g - $b ) / $d ), 6 );
if ($b > $g) { //will have given a negative value for $h
$h += 360;
}
break;
case $g:
$h = 60 * ( ( $b - $r ) / $d + 2 );
break;
case $b:
$h = 60 * ( ( $r - $g ) / $d + 4 );
break;
} //end switch
} //end else
// make any lightness adjustment required
if ($ladj > 0) {
$l += (1 - $l) * $ladj/100;
} elseif ($ladj < 0) {
$l += $l * $ladj/100;
}
//put the values in an array and scale the saturation and lightness to be percentages
$hsl = array( round( $h), round( $s*100), round( $l*100) );
//we could return that, but lets build a CSS compatible string and return that instead
$hslstr = 'hsl('.$hsl[0].','.$hsl[1].'%,'.$hsl[2].'%)';
return $hslstr;
}
在现实生活中,我会将十六进制字符串到 RGB 数组的转换和百分比调整分解为单独的函数,但为了完整起见,将它们包含在此处。
获得 HSL 格式的颜色后,您还可以使用百分比调整来改变色调或饱和度。
function hexToHsl($hex) {
$hex = array($hex[0].$hex[1], $hex[2].$hex[3], $hex[4].$hex[5]);
$rgb = array_map(function($part) {
return hexdec($part) / 255;
}, $hex);
$max = max($rgb);
$min = min($rgb);
$l = ($max + $min) / 2;
if ($max == $min) {
$h = $s = 0;
} else {
$diff = $max - $min;
$s = $l > 0.5 ? $diff / (2 - $max - $min) : $diff / ($max + $min);
switch($max) {
case $rgb[0]:
$h = ($rgb[1] - $rgb[2]) / $diff + ($rgb[1] < $rgb[2] ? 6 : 0);
break;
case $rgb[1]:
$h = ($rgb[2] - $rgb[0]) / $diff + 2;
break;
case $rgb[2]:
$h = ($rgb[0] - $rgb[1]) / $diff + 4;
break;
}
$h /= 6;
}
return array($h, $s, $l);
}
此函数接受 html 十六进制颜色并返回 hsl。在示例中,我生成随机颜色并将其转换为 hsl:
$rgb = "#".substr(hash('crc32b',uniqid()),0,6);
$hsl=rgbToHsl($rgb);
echo "<span style='background:$rgb'>$rgb</span>
<br/>
<span style='background:$hsl'>$hsl</span>";
function rgbToHsl($hexRgb) {
[$r,$g,$b] = sscanf($hexRgb,"#%02x%02x%02x");
$r /= 255;
$g /= 255;
$b /= 255;
$max = max($r, $g, $b);
$min = min($r, $g, $b);
$h = 0;
$s = 0;
$l = ($max + $min) / 2;
if ($max == $min) {
$h = $s = 0;
} else {
$d = $max - $min;
$s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min);
switch ($max) {
case $r:
$h = ($g - $b) / $d + ($g < $b ? 6 : 0);
break;
case $g:
$h = ($b - $r) / $d + 2;
break;
case $b:
$h = ($r - $g) / $d + 4;
break;
}
$h /= 6;
}
$h=round($h*360);
$s=round($s*100);
$l=round($l*100);
return "hsl($h,$s%,$l%)";
}
从 https://css-tricks.com/converting-color-spaces-in-javascript/
的 javascript 重写(并稍作调整)<?php
function hexToHsl($hex)
{
$red = hexdec(substr($hex, 0, 2)) / 255;
$green = hexdec(substr($hex, 2, 2)) / 255;
$blue = hexdec(substr($hex, 4, 2)) / 255;
$cmin = min($red, $green, $blue);
$cmax = max($red, $green, $blue);
$delta = $cmax - $cmin;
if ($delta === 0) {
$hue = 0;
} elseif ($cmax === $red) {
$hue = (($green - $blue) / $delta) % 6;
} elseif ($cmax === $green) {
$hue = ($blue - $red) / $delta + 2;
} else {
$hue = ($red - $green) / $delta + 4;
}
$hue = round($hue * 60);
if ($hue < 0) {
$hue += 360;
}
$lightness = (($cmax + $cmin) / 2) * 100;
$saturation = $delta === 0 ? 0 : ($delta / (1 - abs(2 * $lightness - 1))) * 100;
if ($saturation < 0) {
$saturation += 100;
}
$lightness = round($lightness);
$saturation = round($saturation);
return "hsl(${hue}, ${saturation}%, ${lightness}%)";
}
示例:
<?php
echo hexToHsl('fbffe0'); // outputs 'hsl(68, 100%, 94%)'