Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;“距离”;PHP中的颜色之间_Php_Colors - Fatal编程技术网

&引用;“距离”;PHP中的颜色之间

&引用;“距离”;PHP中的颜色之间,php,colors,Php,Colors,我正在寻找一个函数,可以准确地表示两种颜色之间的距离作为一个数字或东西 例如,我希望有一个十六进制值数组或RGB数组,我想找到给定颜色数组中最相似的颜色 例如,我向函数传递一个RGB值,并返回数组中“最近”的颜色每种颜色都表示为十六进制代码中的元组。要确定紧密匹配,需要分别减去每个RGB分量 例如: Color 1: #112233 Color 2: #122334 Color 3: #000000 Difference between color1 and color2: R=1, G=

我正在寻找一个函数,可以准确地表示两种颜色之间的距离作为一个数字或东西

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


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

每种颜色都表示为十六进制代码中的元组。要确定紧密匹配,需要分别减去每个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) ;

}

一种非常简单的方法是计算三个维度之间的总距离。例如,简单距离(“12,10255”、“10,10250”)=7

一种更复杂的方法是取每个组件的距离平方并求和——这样,过远的组件将受到更多的“惩罚”:平方距离(“12,10255”,“10,10250”)=2*2+0*0+5*5=29


当然,您必须在颜色列表上迭代并找到最接近的颜色。

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

请注意,色调环绕:对于从0到255的色调,0和255的色调非常接近

有关将RGB转换为HSL的公式,请参阅wikipedia关于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…)

上面的公式没有考虑环绕的色调…

,这应该是一个很好的答案

我想把HSL/HSV转换为一个好主意,但后来我意识到,在S/L/V的极端值下,H并不重要,在中间,它最重要。p> 我认为如果你想要一个简单的解决方案,留在RGB空间会更明智。我会使用笛卡尔距离。如果您考虑将颜色
rgb
Ri-Gi-Bi
进行对比,以获得几个
i
,那么您需要最小化的
i

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

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

颜色感知不是线性的

你需要使用一个特殊的公式


看。

类似问题:我知道我需要获得RGB值,但我正在寻找一个函数,它可以返回给定颜色数组中“最相似”的颜色。一个简单的例子:[蓝、红、暗、绿]如果函数的颜色为浅蓝色,从上面的数组中,我希望函数返回“蓝色”欢呼声,如果你根本没有使用十六进制值,只需创建一个带有大switch语句的函数,该语句采用颜色名称,并返回您认为最接近的颜色名称。colofDiff函数很好,但必须修复一个bug作为回报,“return abs($red1-$red2)+abs($green1-$green2)+abs($blue1-$blue2);“我知道这篇文章已经有好几年了。。。但我注意到,对于这项工作,必须改变两件事:1。我们正在寻找最小的diff(为了获得最接近的颜色,对吗?),所以将
colordff($rgbColor,$rgb)>$largestDiff
更改为
,这没有意义。如果颜色A和B的亮度略有不同,色调相同,而颜色A和C的亮度相同,色调差异很大(比如一个是红色,另一个是绿色…),那么A和B之间的距离将大于A和C之间的距离……看来你误解了我提出的顺序:你首先按色调排序,然后按饱和度排序色调相等的颜色,最后按亮度排序色调相等和饱和度相等的颜色。考虑到这种顺序,颜色A和B具有相同的色调,距离(A,B)小于(A,C)。我编辑了我的答案,加入了一个小的数学公式,我希望这有助于更好地理解顺序……对不起,这也没有任何意义。就拿我的第一条评论来说,把“亮度”和“色调”这两个词互换一下,去掉括号里的部分。