1

I know I need to use a loop to look in the $palette Array, but I need help making the color comparison.

GOAL is to find the nearest value of $rgbcolor to $palette and show the color that matches from $palette.

<?php
  //input color
  $rgbcolor = array(110,84,43); 
  //listed color
  $palette = array(
      array(238,216,152),
      array(252,216,113),
      array(253,217,0),
      array(255,208,62),
      array(255,182,20),
      array(206,137,0),
      array(235,169,0),
      array(170,137,0),
      array(173,132,28),
      array(183,131,0),
      array(139,120,37),
      array(108,86,26)
  );
?>
ashleedawg
  • 20,365
  • 9
  • 72
  • 105

1 Answers1

5

There are many different ways to determine color "distance."

There's absolute distance, i.e. the sum of the differences between each channel value:

/**
 * Find the "naive" difference between two colors.
 * @param int[] $color_a Three-element array with R,G,B color values 0-255.
 * @param int[] $color_b Three-element array with R,G,B color values 0-255.
 * @return int
 */
function absoluteColorDistance(array $color_a, array $color_b): int {
    return
        abs($color_a[0] - $color_b[0]) +
        abs($color_a[1] - $color_b[1]) +
        abs($color_a[2] - $color_b[2]);
}

There's also difference in luminosity, which will give more of a color-independent comparison:

/**
 * Find the difference between two colors' luminance values.
 * @param int[] $color_a Three-element array with R,G,B color values 0-255.
 * @param int[] $color_b Three-element array with R,G,B color values 0-255.
 * @return int
 */
function luminanceDistance(int $color_a, int $color_b): int {
    $luminance_f = function ($red, $green, $blue): int {
        // Source: https://en.wikipedia.org/wiki/Relative_luminance
        $luminance = (int) (0.2126 * $red + 0.7152 * $green + 0.0722 * $blue);
        return $luminance;
    };

    return abs(
        $luminance_f($color_a[0], $color_a[1], $color_a[2]) -
        $luminance_f($color_b[0], $color_b[1], $color_b[2])
    );
}

Once you figure out how to compare colors, the next problem you need to solve is finding the color with the least distance from your target color:

$nearest_distance = null;
$nearest_color = null;
foreach ($palate as $test_color) {
    $test_distance = luminanceDistance($test_color, $rgbcolor);
    if (isset($nearest_distance)) {
        if ($nearest_distance > $test_distance) {
            // found a closer color
            $nearest_distance = $test_distance;
            $nearest_color = $test_color;
        }
    } else {
        $nearest_color = $test_color;
        $nearest_distance = $test_distance;
    }
}
amphetamachine
  • 27,620
  • 12
  • 60
  • 72
  • hey . i added 'echo $test_color[0]." ".$test_color[1]." ".$test_color[2]."
    ";' after your // found a closer color but its only returns the last 10 from $palate.. the only one i need is the cloasest one. and show only that one. thankyou.
    – Kim H. McGrail Jul 11 '16 at 19:51
  • @KimH.McGrail The closest color is stored in `$nearest_color` after the `foreach` loop exits. – amphetamachine Jul 11 '16 at 19:54
  • where $color_a, $color_b come from? – Kim H. McGrail Jul 11 '16 at 19:56
  • `$color_a` and `$color_b` are assigned when the `luminanceDistance` function is invoked. Their values are assigned from the arguments passed in to the function call, and they're only defined while the `luminanceDistance` function is executing. – amphetamachine Jul 11 '16 at 19:58
  • THANKYOU @amphetamachine . its flawless. – Kim H. McGrail Jul 11 '16 at 20:03