Php 按颜色分类

Php 按颜色分类,php,sorting,colors,Php,Sorting,Colors,我有一个很长的十六进制颜色列表(1000+),分为一般颜色类别(红色、橙色、蓝色等)。当我显示每个类别中的颜色列表时,我需要按阴影的顺序显示它们。i、 e.首先是浅红色,最后是深红色 算法会是什么呢?(谷歌搜索让我失望)将颜色从RGB转换成比例,然后按值或亮度排序。亮度可能更好,因为它可以更好地捕捉“褪色”的颜色,例如粉色->红色->深红色 如果将颜色转换为HSV空间,则可能会按色调,然后按值对其进行排序 色调将决定颜色“类别”-即:红色、蓝色、绿色等 该值和饱和度将影响最终颜色的“亮度”。不过

我有一个很长的十六进制颜色列表(1000+),分为一般颜色类别(红色、橙色、蓝色等)。当我显示每个类别中的颜色列表时,我需要按阴影的顺序显示它们。i、 e.首先是浅红色,最后是深红色


算法会是什么呢?(谷歌搜索让我失望)

将颜色从RGB转换成比例,然后按值或亮度排序。亮度可能更好,因为它可以更好地捕捉“褪色”的颜色,例如粉色->红色->深红色

如果将颜色转换为HSV空间,则可能会按色调,然后按值对其进行排序

色调将决定颜色“类别”-即:红色、蓝色、绿色等


该值和饱和度将影响最终颜色的“亮度”。不过,你可能需要一些实验才能得到理想的排序。

我知道这个问题很老了,但我没有找到解决这个问题的好办法,所以我做了一些调查,并想分享一下我为假设的未来谷歌用户所做的工作

首先,转换为HSL是一个好主意。但是,当你的颜色没有“分类”时,仅仅按色调或光线分类并不能完全解决这个问题

给定一个如下所示的数组:

$colors = [
            [ 'color' => '#FDD4CD'],
            [ 'color' => '#AE3B3B'],
            [ 'color' => '#DB62A0'],
            ...
          ]
首先,我们将所有十六进制颜色转换为HSL 然后对颜色进行排序 我们比较:

  • 如果它们在相同的“间隔”(interval)中,则它们的色调。因此,我们仅在[0-30]、[30-60]、[60-90]、
  • 如果不在同一时间间隔内,则按亮度排序,如果两者的亮度相同,则按饱和度排序
因此:

usort($colors,function($a,$b){
//在相同的“范围”内比较色调
如果(!huesAreinSameInterval($a['hsl']['h'],$b['hsl']['h'])){
如果($a['hsl']['h']<$b['hsl']['h']))
返回-1;
如果($a['hsl']['h']>$b['hsl']['h'])
返回1;
}
如果($a['hsl']['l']<$b['hsl']['l']))
返回1;
如果($a['hsl']['l']>$b['hsl']['l']))
返回-1;
如果($a['hsl']['s']<$b['hsl']['s']))
返回-1;
如果($a['hsl']['s']>$b['hsl']['s']))
返回1;
返回0;
});
/**
*检查两种色调是否在相同的给定间隔内
*@param float$hue1
*@param float$hue2
*@param int$interval
*@returnbool
*/
函数huesareinsameinval($hue1,$hue2,$interval=30){
return(round($hue1/$interval),0,PHP\u round\u HALF\u DOWN)==round($hue2/$interval),0,PHP\u round\u HALF\u DOWN);
}
在上找到rgbToHsl

在上找到hexToRgb


这里有一个PHP实现(注意DaniWeb弹出窗口),但我不能保证它的质量。感谢链接,我发现这个非常有效:现在正在进行排序,将报告结果。谢谢你的帮助!好的,决赛。使用此类将十六进制转换为其他版本。非常有用:我尝试在HSV上排序,但这似乎不像在RGB值上排序那样正确。然而,这正是我想要的。非常感谢大家的帮助!
foreach ($colors as &$color) {
       $color['hsl'] = hexToHsl($color['color']);
}


/**
 * Convert a hexadecimal color in RGB
 * @param string $hex
 * @return array
 */
function hexToHsl($hex){
    list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
    return rgbToHsl($r, $g, $b);
}

/**
 * Convert a RGB color in its HSL value
 * @param int $r red
 * @param int $g green
 * @param int $b blue
 * @return array
 */
function rgbToHsl($r, $g, $b)
{
    $r /= 255;
    $g /= 255;
    $b /= 255;

    $max = max($r, $g, $b);
    $min = min($r, $g, $b);

    $h = 0;
    $l = ($max + $min) / 2;
    $d = $max - $min;

    if ($d == 0) {
        $h = $s = 0; // achromatic
    } else {
        $s = $d / (1 - abs(2 * $l - 1));

        switch ($max) {
            case $r:
                $h = 60 * fmod((($g - $b) / $d), 6);
                if ($b > $g) {
                    $h += 360;
                }
                break;

            case $g:
                $h = 60 * (($b - $r) / $d + 2);
                break;

            case $b:
                $h = 60 * (($r - $g) / $d + 4);
                break;
        }
    }
    return array('h' => round($h, 2), 's' => round($s, 2), 'l' => round($l, 2));
}
usort($colors, function ($a, $b) {
    //Compare the hue when they are in the same "range"
    if(!huesAreinSameInterval($a['hsl']['h'],$b['hsl']['h'])){
       if ($a['hsl']['h'] < $b['hsl']['h'])
           return -1;
       if ($a['hsl']['h'] > $b['hsl']['h'])
           return 1;
    }
    if ($a['hsl']['l'] < $b['hsl']['l'])
        return 1;
    if ($a['hsl']['l'] > $b['hsl']['l'])
        return -1;
    if ($a['hsl']['s'] < $b['hsl']['s'])
         return -1;
    if ($a['hsl']['s'] > $b['hsl']['s'])
          return 1;
    return 0;
 });

/**
 * Check if two hues are in the same given interval
 * @param float $hue1
 * @param float $hue2
 * @param int $interval
 * @return bool
 */
function huesAreinSameInterval($hue1, $hue2, $interval = 30){
    return (round(($hue1 / $interval), 0, PHP_ROUND_HALF_DOWN) === round(($hue2 / $interval), 0, PHP_ROUND_HALF_DOWN));
}