ColourGradient starting and ending color values incorrect?


#1

Consider the following:

void MyComponent::paint (Graphics& g)
{
  Rectangle <int> const r = getLocalBounds ();
  g.setGradientFill (ColourGradient (
    Colour::fromRGBA (255, 255, 255, 255), r.getX(), r.getY(),
    Colour::fromRGBA (0, 0, 0, 255), r.getX(), r.getBottom(), false));
  g.fillRect (r);
}

Inspection of the output shows the first row with Colour (248, 248, 248) and the last row with Colour (14, 14, 14):

[attachment=0]blend.png[/attachment]


#2

Is that banding as severe as it is in that diagram because the image is a zoomed in sample?

If those bands are actually pixels, then the ‘expected’ image would surely only be guaranteed if the gradient terminated at the vertical centres of the bands… [i.e. y1 = 0.5, y2 = h-0.5]. If white is at y=0, then I imagine the colour in the row of pixels (y=0) would be whatever is halfway between y=0 and y=1.


#3

Yes


#4

Yep, like Haydxn says, I think it’s probably be your expectations that are wrong there.

Each step will change the level by 255/12 = 21ish, so since the colour of each band will be roughly the value at its centre point, which is pretty close to the numbers you’re reporting.


#5

sigh I guess it was asking too much to expect that a vertical blend would look simple with respect to the bounding rectangle? Anyway, I used Haydxn explanation to jigger up this handy object. I only use vertical blends FYI.

// Simple class to facilitate setting vertical blends
//
class VerticalGradient : public JUCE_NAMESPACE::ColourGradient
{
public:
  VerticalGradient (
    Colour const& startColour,
    Colour const& endColour,
    Rectangle <int> const& bounds)
    : ColourGradient (
        startColour, bounds.getX (), bounds.getY () + .5f,
        endColour, bounds.getX (), bounds.getBottom () -.5f,
        false)
  {
  }
};

It would be nice if ColourGradient allowed specification of a ‘gamma’ parameter for each color pair, essentially passing the interpolation value t==[0,1] through the function f(t) = pow (t,g) where g is a gamma value, and g=1 gives the identity. This way I could change the speed of my rolloff towards transparency. Right now I’m doing it by adding points but its clunky and it would be better if it was done when generating the lookup table (since it would be easiest there).