Function that converts hex color values to an approximate color name?

后端 未结 4 1134
谎友^
谎友^ 2020-12-08 17:07

I don\'t suppose anyone knows of a function (PHP, preferably) that can take a hex color code and give an approximate color name for that hex value. I don\'t need a solution

4条回答
  •  我在风中等你
    2020-12-08 17:34

    You have a list of colors here in wikipedia.

    A naive implementation would just calculate the distance between the color whose name you want to retrieve and every one of those and output the one that's closer.

    If you see the colors as vectors in R3, you could calculate the distance as L1 norm:

    function distancel1(array $color1, array $color2) {
        return abs($color1[0] - $color2[0]) + 
            abs($color1[1] - $color2[1]) +
            abs($color1[2] - $color2[2]);
    }
    

    or the L2 norm:

    function distancel2(array $color1, array $color2) {
        return sqrt(pow($color1[0] - $color2[0], 2) +
            pow($color1[1] - $color2[1], 2) +
            pow($color1[2] - $color2[2], 2));
    }
    

    For converting the hexadecimal notation, see here.

    Example script:

     array(0, 0, 0),
        "green"     => array(0, 128, 0),
        "silver"    => array(192, 192, 192),
        "lime"      => array(0, 255, 0),
        "gray"      => array(128, 0, 128),
        "olive"     => array(128, 128, 0),
        "white"     => array(255, 255, 255),
        "yellow"    => array(255, 255, 0),
        "maroon"    => array(128, 0, 0),
        "navy"      => array(0, 0, 128),
        "red"       => array(255, 0, 0),
        "blue"      => array(0, 0, 255),
        "purple"    => array(128, 0, 128),
        "teal"      => array(0, 128, 128),
        "fuchsia"   => array(255, 0, 255),
        "aqua"      => array(0, 255, 255),
    );
    
    $value = "#819001";
    
    function html2rgb($color)
    {
        if ($color[0] == '#')
            $color = substr($color, 1);
    
        if (strlen($color) == 6)
            list($r, $g, $b) = array($color[0].$color[1],
                                     $color[2].$color[3],
                                     $color[4].$color[5]);
        elseif (strlen($color) == 3)
            list($r, $g, $b) = array($color[0].$color[0],
                $color[1].$color[1], $color[2].$color[2]);
        else
            return false;
    
        $r = hexdec($r); $g = hexdec($g); $b = hexdec($b);
    
        return array($r, $g, $b);
    }
    
    function distancel2(array $color1, array $color2) {
        return sqrt(pow($color1[0] - $color2[0], 2) +
            pow($color1[1] - $color2[1], 2) +
            pow($color1[2] - $color2[2], 2));
    }
    
    $distances = array();
    $val = html2rgb($value);
    foreach ($colors as $name => $c) {
        $distances[$name] = distancel2($c, $val);
    }
    
    $mincolor = "";
    $minval = pow(2, 30); /*big value*/
    foreach ($distances as $k => $v) {
        if ($v < $minval) {
            $minval = $v;
            $mincolor = $k;
        }
    }
    
    echo "Closest color: $mincolor\n";
    

提交回复
热议问题