Переводим число из HEX.
// писал по памяти, не уверен что заведется
$rgb = array_map($component) {
return base_convert($component, 16, 10);
}, array_chunk(ltrim($color, '#'), 2));
И теперь мы можем вычислить расстояние между цветами по формуле:
d=sqrt((r2-r1)^2+(g2-g1)^2+(b2-b1)^2)
По расстоянию находим наиболее близкий цвет.
Еще как вариант - перевести цвет в HSV и сравнивать по среднему значению компоненты HUE. Если у вас большая палитра, то будет дешевле в плане вычислений один раз перевести RGB в HSV и потом считать только среднее значение.
Итоговый вариант:
// преобразует HEX в RGB
function hexToRgb($hex)
{
return array_map($component) {
return base_convert($component, 16, 10);
}, array_chunk(ltrim($hex, '#'), 2));
}
// возвращает расстояние между двумя цветами
function getDistanceFromColor($a, $b)
{
list($r1, $g1, $b1) = $a;
list($r2, $g2, $b2) = $b;
return sqrt(pow($r2-$r1, 2)+pow($g2-$g1, 2)+pow($b2-$b1, 2));
}
// Возвращает наиболее подходящий цвет из палитры
function getClosestColor($color, array $pallet) {
$distances = array_map(function ($colorFromPallet) use ($color) {
return getDistanceFromColor($color, $colorFromPallet);
}, $pallet);
ksort($distances);
$keys = array_keys($distances);
return $pallet[$keys[0]];
}
// пример:
$color = "#ff0044";
// для примера у нас есть палитра из HEX цветов
$pallet = ["#ff0000", "#ffffff"];
// сразу переводим в RGB всю палитру
$pallet = array_map(function ($color) {
return hexToRgb($color);
}, $pallet);
// берем самый подходящий в палитре цвет
// он вернется в формате RGB, можете потом сконвертить в HEX
$closestColor = getClosestColor($color, $pallet);
для картинки можно сделать проще - пусть функция getClosestColor будет возвращать индекс цвета из палитры. Так проще организовать подсчет и мы все так же знаем на какой цвет заменять.