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

122
9

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


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


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

спросил(а) 2009-10-28T00:39:00+03:00 10 лет, 3 месяца назад
1
Решение
151

Каждый цвет представлен как кортеж в 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) ;

}

ответил(а) 2009-10-28T00:47:00+03:00 10 лет, 3 месяца назад
121

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


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

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


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

ответил(а) 2009-10-28T01:06:00+03:00 10 лет, 3 месяца назад
103

Сначала вам нужно выбрать подходящее цветовое пространство, в котором вы хотите сравнить цвета (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;

ответил(а) 2009-10-28T02:09:00+03:00 10 лет, 3 месяца назад
77

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


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


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

ответил(а) 2009-10-28T00:49:00+03:00 10 лет, 3 месяца назад
49

Восприятие цвета не является линейным потому что человеческий глаз более чувствителен к определенным цветам, чем другие.


Вам нужно использовать специальную формулу.


Посмотрите здесь.

ответил(а) 2013-10-21T16:19:00+04:00 6 лет, 4 месяца назад
50

вы можете преобразовать значение 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...)


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

ответил(а) 2009-10-28T00:58:00+03:00 10 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема