Jump to content

[SOLVED] Sorting Color Swatches based off from RGB info.


mrln68

Recommended Posts

I am trying to figure out a way to sort a series of different color swatches into a color wheel type sequence (Reds, Oranges, Yellows, Greens, Blues, Violets...) based on their RGB color information.  I know how to get the information I need, and I know how to display the information I need...I just can figure out the best way to sort the individual RGB datasets without doing it manually (and with well over 400 of them, I would rather not do it that way).

 

I've checked through the gd library to see if I could find anything that might work, but unless I am missing something - that is a dead end...so I am thinking maybe there is an equation which applies to RGB color coding that would work, it is just not something I know of.

I saw this as a bit of a challenge, I love messing around with colours and images so here's my solution to your problem - This only sorts in a linear fashion though I guess could be tweaked to display in an RGB grid given some more time...

 

My solution converts an array of RGB colours to their equivalent HSV values, then sorts in order of hue, saturation, then value. Then I converted the colours back to RGB and displayed them. On to the code... (Which builds an array of 400 random colours, then sorts them)

 

<?php
function swatch() {
    //Return an RGB array
    $r = ceil(rand(0,255));
    $g = ceil(rand(0,255));
    $b = ceil(rand(0,255));
    return array($r,$g,$b);
}

function rgbtohsv($r,$g,$b) {
    //Convert RGB to HSV
    $r /= 255;
    $g /= 255;
    $b /= 255;
    $min = min($r,$g,$b);
    $max = max($r,$g,$b);

    switch($max) {
        case 0:
            $h = $s = $v = 0;
            break;
        case $min:
            $h = $s = 0;
            $v = $max;
            break;
        default:
            $delta = $max - $min;
            if($r == $max) {
                $h = 0 + ($g - $b) / $delta;
            } elseif($g == $max) {
                $h = 2 + ($b - $r) / $delta;
            } else {
                $h = 4 + ($r - $g) / $delta;
            }
            $h *= 60;
            if($h < 0 ) $h += 360;
            $s = $delta / $max;
            $v = $max;
        }
        return array($h,$s,$v);
}

function hsvtorgb($h,$s,$v) {
    //Convert HSV to RGB
    if($s == 0) {
        $r = $g = $b = $v;
    } else {
        $h /= 60.0;
        $s = $s;
        $v = $v;

        $hi = floor($h);
        $f = $h - $hi;
        $p = ($v * (1.0 - $s));
        $q = ($v * (1.0 - ($f * $s)));
        $t = ($v * (1.0 - ((1.0 - $f) * $s)));

        switch($hi) {
            case 0: $r = $v; $g = $t; $b = $p; break;
            case 1: $r = $q; $g = $v; $b = $p; break;
            case 2: $r = $p; $g = $v; $b = $t; break;
            case 3: $r = $p; $g = $q; $b = $v; break;
            case 4: $r = $t; $g = $p; $b = $v; break;
            default: $r = $v; $g = $p; $b = $q; break;
        }
    }
    return array(
        (integer) ($r * 255 + 0.5),
        (integer) ($g * 255 + 0.5),
        (integer) ($b * 255 + 0.5)
    );
}

//Create an array of random RGB colours converted to HSV
$s = array();
for($i=0; $i<400; $i++) {
    list($r,$g,$b) = swatch();
    $s[] = rgbtohsv($r,$g,$b);
}

//Split each array up into H, S and V arrays
foreach($s as $k => $v) {
    $hue[$k] = $v[0];
    $sat[$k] = $v[1];
    $val[$k] = $v[2];
}

//Sort in ascending order by H, then S, then V and recompile the array
array_multisort($hue,SORT_ASC,$sat,SORT_ASC,$val,SORT_ASC,$s);

//Display
foreach($s as $k => $v) {
    list($hue,$sat,$val) = $v;
    list($r,$g,$b) = hsvtorgb($hue,$sat,$val);
    echo "<div style='border:1px solid #000;padding:4px;background:rgb($r,$g,$b);'>$r,$g,$b</div>";
}
?>

 

Hope this helps out :)

That will work well enough, though there are some anomolies that I am not quite sure how to deal with (#BF5D40, #E7886A, #928F8E, #783620, #DD3C06 - are 5 different colors which are in my list...sorted, one however stands a good bit out from the others).

 

Curious though - since you enjoy colors and what not, are you familiar with CIE 1994 color matching?  I can understand the math itself easy enough, it is wrapping my head around what it is actually doing that causes the headache.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.