3

I need for a projet to get a color from a value. I explain, I have datas and each data must be represented by a color.

The red color is for the maximum, and the blue for the minimum and the green is for the middle value. A kind of heatmap.

So, I need to have a function returning the right color.

I tried something like this :

    function datatocolor($min, $max, $value)
    {
        $half = (($min + $max) / 2);

        if ($value > $half)
        {
            $r = (255 * ($value+$min-$half)) / $half;
            $g = 255 - $r;
            $b = 0;
        } 
        else {
            $b = (255 * ($half-$value+$min)) / $half;
            $g = 255 - $b;
            $r = 0;         
        }
        $color = array(intval($r), intval($g),  intval($b));
        return $color;
    }

But, I get red and blue, and never green ... I tried a lot of operations, I must be stupid but I don't find the right operation ... Thanks in advance for your help !

Julian T
  • 35
  • 6

1 Answers1

2

I'm not a php expert, but as far as I can tell, the problem isn't with this code block. I tested your algorithm in java just to be sure, and it looks to be correct:

public static void main(String[] args) {
    int min = 0;
    int max = 10;
    int half = (min + max) / 2;

    int r, g, b;

    // Cycling through the values for completeness' sake.
    for (int value = 0; value <= 10; value++) {
        if (value > half) {
        r = (255 * (value + min - half)) / half;
        g = 255 - r;
        b = 0;
    } else {
        b = (255 * (half - value + min)) / half;
        g = 255 - b;
        r = 0;
    }
    System.out.println("Value: " + value + " - " + new Color(r, g, b));
}

The output from this is what you would expect -- pure blue at minimum, pure green at the middle, and pure red at the maximum:

Value: 0 - java.awt.Color[r=0,g=0,b=255]
Value: 1 - java.awt.Color[r=0,g=51,b=204]
Value: 2 - java.awt.Color[r=0,g=102,b=153]
Value: 3 - java.awt.Color[r=0,g=153,b=102]
Value: 4 - java.awt.Color[r=0,g=204,b=51]
Value: 5 - java.awt.Color[r=0,g=255,b=0]
Value: 6 - java.awt.Color[r=51,g=204,b=0]
Value: 7 - java.awt.Color[r=102,g=153,b=0]
Value: 8 - java.awt.Color[r=153,g=102,b=0]
Value: 9 - java.awt.Color[r=204,g=51,b=0]
Value: 10 - java.awt.Color[r=255,g=0,b=0]

Based on what you've provided, the problem seems to be either in the way you're calling the function, or in the way you're using the array it returns.

  • Thanks for your test, it's work yes, but I want to have a HSV scale. That means : Red -> Orange -> Yellow -> Green -> Cyan -> Blue. I continue to seek ... :) – Julian T Jul 22 '11 at 11:22
  • A quick Google search for `php hsv` yields a handful of conversion functions between RGB and HSV color spaces. – Argumentum ad Stultitiam Jul 22 '11 at 14:03
  • Yes I found the functions to convert in HSV. But, I think I need to convert my values to HSV format, then to RGB to have the right gradient... – Julian T Jul 22 '11 at 14:24
  • For a quick solution, you can simply have a set `$s` and `$v`, calculate `$h` between min/blue and max/red, and run the result through a converter function to get your RGB value. But now we're in the messy world of colors and computing, so you may want to create a new question if you're still having trouble. – Argumentum ad Stultitiam Jul 22 '11 at 15:18
  • Thanks for this answer, I will try this method, but I am (of course) in trouble to get the $v and $h values. I will post a new question... – Julian T Jul 25 '11 at 12:55