PHP中颜色之间的“距离”

时间:2009-10-27 21:39:55

标签: php colors

我正在寻找一种能够准确地将两种颜色之间的距离表示为数字或类似物的功能。

例如我希望有一个HEX值或RGB数组的数组,我想在给定颜色的数组中找到最相似的颜色

例如。我传递一个RGB值的函数,并返回数组中“最接近的”颜色

6 个答案:

答案 0 :(得分:19)

每种颜色在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) ;

}

答案 1 :(得分:13)

Here is a paper on the subject应该给出一个好的答案。

我当时认为首先转换为HSL / HSV也是一个好主意,但后来我意识到S&的极端值。 L / V,H无关紧要,中间最重要。

我认为如果你想要一个简单的解决方案,留在RGB空间会更明智。我会用笛卡尔距离。如果您针对多个R G B针对Ri Gi Bi考虑颜色i,则需要最小化的i

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

答案 2 :(得分:8)

首先,你必须选择你想要进行颜色比较的适当颜色空间(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;

答案 3 :(得分: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

当然,您必须遍历颜色列表并找到最接近的颜色。

答案 4 :(得分:1)

您可以将RGB值转换为HSL或HSV。然后颜色很容易比较:首先按色调排序颜色,然后按饱和度排序,然后按亮度排序。在生成的顺序中,彼此相邻的两种颜色将在感知上非常接近。

请注意色调环绕:色调范围为0到255,色调为0,色调为255非常接近。

请参阅有关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 ......)

以上公式没有考虑到色调环绕......

答案 5 :(得分:1)

颜色感知不是线性because the human eye is more sensitive to certain colors than others.

您需要使用特殊的公式。

here