且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将十六进制颜色值转换为近似颜色名称的函数?

更新时间:2023-01-27 10:42:22

您有一系列颜色在这里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.

如果您在R3中看到颜色作为向量,您可以将距离计算为L1范数:

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]);
}

或L2规范:

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.

示例脚本:

<?php

$colors = array(
    "black"     => 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";