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.

Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

At least that makes me feel a little better...though I would honestly have prefered it being something which my feeble mind just couldn't grasp.

 

BTW - You might want to take a look at easyrgb.com for a bit of gee whiz info.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.