How does this code work to get a nice color gradient?

edited January 2014 in Questions about Code

I want to make a nice color gradient and be able to change the colors and number of colors in the gradient. I looked on the forum and found some code (posted by Poersch) that can do this very easy. The problem is I don't understand how it works.

I Made a small sketch to test it:

PImage gradientMap; // This PImage object will hold the gradient

void setup() {
    size(200, 200);
    noStroke();

    // Define as much colors as you like
    color[] colors = new color[] { color(255, 0, 0), color(255, 255, 0), color(0, 255, 0), color(0, 0, 255) };

    // Create gradient map from the given colors
    gradientMap = createImage(1, colors.length, RGB);
    gradientMap.loadPixels();
    for(int n = 0; n < colors.length; n++)
    gradientMap.pixels[n] = colors[n];
    gradientMap.updatePixels();

    noLoop();
}

// Render sketch
void draw() {
 image(gradientMap,0,0,200,200);
}

I don't understand how the gradientMap.pixels[n] = colors[n] can generate more colors than there are in the colors array? Can anyone explain it to me, Thanks

Answers

  • I, think it has something to do with stretching the image out. Like the gradientMap is only 1x5 pixels large. And when you create an image of 200x200 it interpolates between the colors and fills up the space with that.

    Is this always the case? And how does image do this then?

  • Answer ✓

    that's right - when you resize an image it interpolates it to fit the requested size.

    image interpolation is a big topic - there are lots of ways of doing it. read this if you're interested - http://en.wikipedia.org/wiki/Image_scaling

    i'm not sure which method processing uses but i'd guess bicubic as a compromise between quality and speed.

  • OK, thanks.

    I played a bit with the code to create a custom legend for a heatmap.

    I think this is an efficient way of interpolating between the colors by letting the image function do it for you :)

  • edited January 2014

    Good to know that someone uses my code! :D

    Yes, Processing uses bicubic filtering as standard. You can alter the filtering mode by using the noSmooth/smooth() function:

    noSmooth() = nearest neighbor (no) interpolation

    smooth(1 - 3) = linear interpolation

    smooth(4+) = bicubic interpolation

    Atm. this just works with the default renderer (Java2D), but will be added to the other renderers soon (reference).

  • Thanks Poersch for the info (and the code :) ). I will play a bit with the smooth function to see what the effect is and what works best for me.

Sign In or Register to comment.