Подтвердить что ты не робот

"Расстояние" между цветами в PHP

Я ищу функцию, которая может точно представлять расстояние между двумя цветами как число или что-то.

Например, я ищу массив массивов значений HEX или RGB-массивов, и я хочу найти наиболее похожий цвет в массиве для заданного цвета

например. Я передаю функцию значение RGB, и возвращается "ближайший" цвет в массиве

4b9b3361

Ответ 1

Каждый цвет представлен как кортеж в HEX-коде. Чтобы определить близкие совпадения, вам нужно вычесть каждый компонент RGB отдельно.

Пример:

Color 1: #112233 
Color 2: #122334
Color 3: #000000

Difference between color1 and color2: R=1,  G=1   B=1  = 0x3 
Difference between color3 and color1: R=11, G=22, B=33 = 0x66

So color 1 and color 2 are closer than
1 and 3.

изменить

Итак, вам нужен самый близкий цвет? Создайте массив с шестнадцатеричными значениями каждого цвета, повторите его и верните имя. Что-то вроде этого;

function getColor($rgb)
{
    // these are not the actual rgb values
    $colors = array(BLUE =>0xFFEEBB, RED => 0x103ABD, GREEN => 0x123456);

    $largestDiff = 0;
    $closestColor = "";
    foreach ($colors as $name => $rgbColor)
    {
        if (colorDiff($rgbColor,$rgb) > $largestDiff)
        {
            $largestDiff = colorDiff($rgbColor,$rgb);
            $closestColor = $name;
        }

    }
    return $closestColor;

}

function colorDiff($rgb1,$rgb2)
{
    // do the math on each tuple
    // could use bitwise operates more efficiently but just do strings for now.
    $red1   = hexdec(substr($rgb1,0,2));
    $green1 = hexdec(substr($rgb1,2,2));
    $blue1  = hexdec(substr($rgb1,4,2));

    $red2   = hexdec(substr($rgb2,0,2));
    $green2 = hexdec(substr($rgb2,2,2));
    $blue2  = hexdec(substr($rgb2,4,2));

    return abs($red1 - $red2) + abs($green1 - $green2) + abs($blue1 - $blue2) ;

}

Ответ 2

Вот документ по теме, который должен дать хороший ответ.

Я думал, что преобразование в HSL/HSV сначала было бы хорошей идеей, но потом я понял, что при экстремальных значениях S и L/V H не имеет значения, а в середине это имеет значение больше всего.

Я думаю, что если вы хотите простое решение, пребывание в RGB-пространстве было бы мудрее. Я бы использовал декартовую дистанцию. Если вы рассматриваете цвет R G B для Ri Gi Bi для нескольких i, вы хотите, чтобы i минимизировал

(R - Ri)^2 + (G - Gi)^2 + (B - Bi)^2

Ответ 3

Сначала вам нужно выбрать подходящее цветовое пространство, в котором вы хотите сравнить цвета (RGB, HSV, HSL, CMYK и т.д.).

Предполагая, что вы хотите знать, как близки две точки в трехмерном пространстве RGB друг к другу, вы можете рассчитать расстояние между ними Пифагора, т.е.

d2 = (r1 - r2)**2 + (g1 - g2)**2 + (b1 - b2)**2;

Это фактически дает вам квадрат расстояния. (Принимать квадратный корень не нужно, если вы сравниваете только квадратичные значения.)

Это предполагает, что вы хотите одинаково относиться к значениям R, G и B. Если вы хотите весить отдельные цветовые компоненты, например, что происходит при преобразовании RGB в оттенки серого, вам нужно добавить коэффициент к каждому члену расстояния, т.е.

d2 = 30*(r1-r2)**2 + 59*(g1-g2)**2 + 11*(b1-b2)**2;

Это предполагает, что популярное преобразование из RGB в оттенки серого составляет 30% красного + 59% зеленого + 11% голубого.

Обновление

Последнее уравнение должно быть

d2 = (30*(r1-r2))**2 + (59*(g1-g2))**2 + (11*(b1-b2))**2;

Ответ 4

Очень простой подход - рассчитать суммарное расстояние между тремя измерениями. Например, simple_distance ( "12,10,255", "10,10,250" ) = 7

Более сложный подход состоял бы в том, чтобы взять квадрат расстояний для каждого компонента и суммировать их - таким образом, компоненты, находящиеся слишком далеко, будут "наказаны" больше: square_distance ( "12,10,255", "10,10,250" ) = 2 * 2 + 0 * 0 + 5 * 5 = 29.

Конечно, вам придется перебирать список цветов и находить ближайший.

Ответ 5

вы можете преобразовать значение RGB в HSL или HSV. то цвета легко сравнивать: сначала заказывайте цвета по оттенку, затем по насыщенности, затем по яркости. в полученном порядке 2 цвета рядом друг с другом будут выглядеть очень близко перцептивно.

Остерегайтесь того, что оттенок обтекает: для оттенка от 0 до 255, оттенок 0 и оттенок 255 очень близки.

см. статью wikipedia о HSL http://en.wikipedia.org/wiki/HSL_and_HSV для формулы, которая позволит вам конвертировать RGB в HSL

(обратите внимание, что другие цветовые пространства, такие как L.a.b., могут давать лучшие результаты, но преобразование сложнее)

определим это математически:

distance(A(h,s,l), B(h,s,l)) = (A(h)-B(h)) * F^2 + (A(s)-B(s)) * F + (A(l)-B(l))

где F - это тщательно подобранный фактор (что-то вроде 256...)

приведенная выше формула не учитывает оттенок...