Le tri par Couleur

J'ai une longue liste (1000+) de couleurs hexadécimales réparties dans les catégories de couleurs générales (Rouge, Orange, Bleu, etc.). Lorsque je montre la liste des couleurs dans chaque catégorie, je dois les montrer par ordre d'ombre. c'est-à-dire rouge clair en premier et rouge foncé en dernier.

Quel serait l'algorithme pour faire cela? (googling m'a échoué)

23
demandé sur user154442 2009-08-11 19:17:43

3 réponses

Convertissez les couleurs de RVB à une échelle HSV ou HSL, puis triez-les par valeur ou légèreté. La légèreté pourrait mieux fonctionner car elle capturerait mieux les couleurs" fanées", telles que Rose->rouge->rouge foncé.

Conversion D'espace colorimétrique RVB vers HSV .

8
répondu James Schek 2009-08-11 15:25:58

Je sais que cette question Est ancienne, mais je n'ai pas trouvé de solution à ce problème, alors j'étudie un peu et je veux partager ce que j'ai fait pour de futurs googlers hypothétiques.

Tout d'abord, convertir en HSL est une excellente idée. Mais trier uniquement par teinte ou lumière n'a pas résolu complètement le problème lorsque vos couleurs ne sont pas "classées".

Étant Donné un tableau qui ressemble à:

$colors = [
            [ 'color' => '#FDD4CD'],
            [ 'color' => '#AE3B3B'],
            [ 'color' => '#DB62A0'],
            ...
          ]

D'abord, nous convertissons toutes les couleurs hexadécimales en HSL

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));
}

, Puis trier les couleurs

Nous comparer:

  • leur teinte si elles sont dans le même ' intervalle '(cela aide à comprendre pourquoi je choisis 30°). Nous comparons donc la teinte seulement si les deux sont dedans [0-30], [30-60], [60-90],...
  • si ce n'est pas dans le même intervalle, Trier par leur légèreté, puis par saturation si les deux partagent la même légèreté.

Donc:

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));
}

Rgbtohsl trouvé sur www.brandonheyer.com

HexToRgb trouvé sur stackoverflow

11
répondu Getz 2017-05-23 11:52:58

Si vous convertissez les couleurs en espace HSV, vous pouvez potentiellement les Trier par la teinte, puis la valeur.

La teinte déterminera la couleur "catégorie" - à savoir: Rouge, bleu,vert, etc.

La valeur et la saturation affecteront la "légèreté" de la couleur finale. Vous pourriez avoir besoin d'expérimentation pour obtenir le genre idéal, cependant.

1
répondu Reed Copsey 2009-08-11 15:22:13