"Расстояние" между цветами в PHP
Я ищу функцию, которая может точно представлять расстояние между двумя цветами как число или что-то.
Например, я ищу массив массивов значений HEX или RGB-массивов, и я хочу найти наиболее похожий цвет в массиве для заданного цвета
например. Я передаю функцию значение RGB, и возвращается "ближайший" цвет в массиве
Ответы
Ответ 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...)
приведенная выше формула не учитывает оттенок...
Ответ 6
Восприятие цвета не является линейным потому что человеческий глаз более чувствителен к определенным цветам, чем другие.
Вам нужно использовать специальную формулу.
Посмотрите здесь.