Функция, которая преобразовывает шестнадцатеричные значения цвета в приблизительное название цвета?

Я не предполагаю, что любой знает о функции (PHP, предпочтительно), который может взять шестнадцатеричный цветовой код и дать приблизительное название цвета того шестнадцатеричного значения. Мне не нужно решение с 100 с цветов. Даже если бы это просто составило цвета белый, черный, красный, зеленый синий, коричневый оранжевый и желтый цвет, то я был бы вполне прилично в форме.

Если Вы не знаете о существующем ресурсе, кто-либо знает о хорошем способе приблизиться к этой проблеме?

Заранее спасибо за справку.

15
задан dclowd9901 7 June 2010 в 23:55
поделиться

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";
24
ответ дан 1 December 2019 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: