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

2022-08-30 22:59:13

我不认为有人知道一个函数(最好是PHP),它可以采用十六进制颜色代码并为该十六进制值提供近似的颜色名称。我不需要100多种颜色的解决方案。即使它只是相当于白色,黑色,红色,绿色蓝色,棕色橙色和黄色的颜色,我的身材也会很好。

如果您不知道现有的资源,有没有人知道解决此问题的好方法?

提前感谢您的帮助。


答案 1

在维基百科上有一个颜色列表。

一个幼稚的实现只会计算要检索其名称的颜色与其中每一种颜色之间的距离,并输出更接近的颜色。

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

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

有关转换十六进制表示法的信息,请参阅此处

示例脚本:

<?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";

答案 2

使用Artefacto答案中使用的wiki链接,我抓取了所有颜色名称,并形成了一个包含1,175个颜色名称的数组。不幸的是,Stackoverflow只允许在答案中包含30,000个字符,所以这是链接


推荐