如何使用PHP检测“浅色”颜色

php
2022-08-30 16:29:47

我正在处理一个动态商店项目,我使用循环将产品的所有颜色选项打印为颜色框,但是我真的需要为这些浅色添加“边框”。我尝试了类似下面的东西,但它非常有限,它实际上仅限于白色,它不会捕捉到像#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;
        }
    }
}

Colors是来自后端的数组,例如:White,#000,#cc0000等。在if/else条件下添加所有异常是不切实际的,任何快速的想法?


答案 1

将 HTML 颜色转换为 RGB,然后转换为色相饱和度-浅色 (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!
}

源:

演示:


答案 2

在这种情况下,我要做的是使用HSL检测颜色的亮度,并将其与一定百分比进行比较。例如,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
}

上面的函数将返回您选择的颜色的亮度百分比(为此也需要简单的十六进制->rgb转换,但这应该很容易)。我除以510而不是2的原因是,为了在除以2获得百分比,你除以255。为了加快速度,您可以简单地说:.然后,我将上述函数返回的值与 80% 进行比较。(x / 2) / 255 = x / 510

$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
}

推荐