Я работаю над проектом динамического хранилища, и я использую цикл для печати всех цветовых параметров для продукта в виде цветовых ящиков, однако мне действительно нужно добавить «границу» к этим цветам, которые являются легкими. Я пробовал что-то вроде следующего, но он очень ограничен, он фактически ограничен только белым цветом, он не поймает что-то вроде #ddd, #eea … и т. Д.
Вот моя петля:
foreach($colors as $color) { $color = trim($color); if (!empty($color)) { if (in_array($color, array('white','White','#fff','#FFF','#FFFFFF','#ffffff'))) { $bordercolor = '#bbb'; } else { $bordercolor = $color; } } }
Цвета – это массив из бэкэнда, например: Белый, # 000, # cc0000 и т. Д. Нецелесообразно добавлять все исключения в условие if / else, любую быструю идею?
Преобразование цвета HTML в RGB, затем в Hue-Saturation-Lightnes (HSV)
<?php function HTMLToRGB($htmlCode) { if($htmlCode[0] == '#') $htmlCode = substr($htmlCode, 1); if (strlen($htmlCode) == 3) { $htmlCode = $htmlCode[0] . $htmlCode[0] . $htmlCode[1] . $htmlCode[1] . $htmlCode[2] . $htmlCode[2]; } $r = hexdec($htmlCode[0] . $htmlCode[1]); $g = hexdec($htmlCode[2] . $htmlCode[3]); $b = hexdec($htmlCode[4] . $htmlCode[5]); return $b + ($g << 0x8) + ($r << 0x10); } function RGBToHSL($RGB) { $r = 0xFF & ($RGB >> 0x10); $g = 0xFF & ($RGB >> 0x8); $b = 0xFF & $RGB; $r = ((float)$r) / 255.0; $g = ((float)$g) / 255.0; $b = ((float)$b) / 255.0; $maxC = max($r, $g, $b); $minC = min($r, $g, $b); $l = ($maxC + $minC) / 2.0; if($maxC == $minC) { $s = 0; $h = 0; } else { if($l < .5) { $s = ($maxC - $minC) / ($maxC + $minC); } else { $s = ($maxC - $minC) / (2.0 - $maxC - $minC); } if($r == $maxC) $h = ($g - $b) / ($maxC - $minC); if($g == $maxC) $h = 2.0 + ($b - $r) / ($maxC - $minC); if($b == $maxC) $h = 4.0 + ($r - $g) / ($maxC - $minC); $h = $h / 6.0; } $h = (int)round(255.0 * $h); $s = (int)round(255.0 * $s); $l = (int)round(255.0 * $l); return (object) Array('hue' => $h, 'saturation' => $s, 'lightness' => $l); } $colour = '#F12346'; $rgb = HTMLToRGB($colour); $hsl = RGBToHSL($rgb); var_dump($hsl);
Применение:
$colour = '#F12346'; $rgb = HTMLToRGB($colour); $hsl = RGBToHSL($rgb); if($hsl->lightness > 200) { // this is light colour! }
Источник:
Демо-версия:
То, что я сделаю в этой ситуации, – это выявить легкость цвета с использованием HSL и сравнить его с определенным процентом. Например, атрибут lightness в алгоритме HSL принимает цветность (M – m, где M – наибольшее значение RGB, а m – наименьшее значение RGB) и делит его на 2.
function lightness($R = 255, $G = 255, $B = 255) { return (max($R, $G, $B) + min($R, $G, $B)) / 510.0; // HSL algorithm }
Вышеупомянутая функция вернет процент от того, насколько свет вы выбрали (для этого также нужны простые преобразования hex -> rgb, но это должно быть довольно легко). Причина, по которой я разделил 510 вместо 2, состоит в том, что для того, чтобы получить процент после деления на 2, вы делите на 255. Чтобы сделать это быстрее, вы можете просто сказать: (x / 2) / 255 = x / 510
. Затем я сравнил значение, возвращаемое указанной функцией, например, 80%.
$r = hexdec($hex[0].$hex[1]); $g = hexdec($hex[2].$hex[3]); $b = hexdec($hex[4].$hex[5]); if(lightness($r, $g, $b) >= .8) { // add border } else { // no border }
В дополнение к другим формулам, предоставленным другими ответами, вы можете рассмотреть Luma .
function luma($r, $g, $b) { return (0.2126 * $r + 0.7152 * $g + 0.0722 * $b) / 255; } $l = luma(0, 15, 255);
Значения ближе к 0 будут более темными. Значения ближе к 1 будут легче.
Существует также более простой способ с еще меньшим количеством кода:
<?php //Functions function getRGB($colorCode) { //Turn html color code into RGB $var_R = substr($colorCode, 0, 2); $var_G = substr($colorCode, 2, 2); $var_B = substr($colorCode, 4, 2); //Get Hex values $val_R = hexdec($var_R); $val_G = hexdec($var_G); $val_B = hexdec($var_B); //Red is seen as light too, gets fixed with this $remRed = hexdec('99'); if ($val_R > $remRed) { $RGB = $val_G.' '.$val_B; } else { $RGB = $val_R.' '.$val_G.' '.$val_B; } return $RGB; } function getHSL($R = 255, $G = 255, $B = 255) { $hsl = (max($R, $G, $B) + min($R, $G, $B)) / 510.0; return $hsl; } ?>
Теперь вызов:
$color = 0000FF; //Blue $RGBcode = getRGB($color); //Returns 0 0 255 $RGBcode = str_replace(' ', ', ', $RGBcode); //Replaces an empty space with a , $val_HSL = getHSL($RGBcode); //Returns value from 0.5 to 1 if ($val_HSL >= 0.8) { //Reject color } else { //Accept Color $color = '#'.$color; //Sets it to html: #0000FF }
Короткий путь, если у вас есть цвет RGB:
$hex = "4488BB"; if(hexdec(substr($hex,0,2))+hexdec(substr($hex,2,2))+hexdec(substr($hex,4,2))> 382){ //bright color }else{ //dark color }