HSB values are altered

I want to use HSB colormode, and in setup I’ve added:

colorMode(HSB,360,100,100);

For some reason the colors in my code are not retained as HSB values and are therefore altered when i use fill() followed by rect(). I can only guess, but it appears that some sort of implicit color format conversion takes place somewhere against my will.

I realize this can be tricky to answer without seeing all my code, but is there a simple explanation for this?

I am using colorMode() once in setup(), and am only copying values without any other calculations of color values, so how can the colors be altered in this manner?

colorMode defines how the colour parameter in commands such as fill, background etc are to be interpreted. Internally all colours are stored as 32 bit integers using ARGB values.

1 Like

Hi @Erik,

The color mode remains as long as no other color mode is set and processing internally is not changing this.
Maybe you can demonstrate on a simple example how you are using color mode, fill, etc. and having such an odd behavior…

Cheers
— mnse

2 Likes

Hello @Erik,

Some resources here that may provide insight:

Source code:

:)

Thanks for your feedback, here’s an example imitating my project. I’ve tried to make my example as short as possible:

TestPalette.pde:

void setup() {
    size(1080, 1080);
    colorMode(HSB,360,100,100);
    noStroke();

    drawColorSwatches();
}

void main() {  
}

Constants.pde:

final color red =         color(0, 100, 100);
final color yellow =      color(60, 100, 100);
final color green =       color(120, 100, 100);
final color blue =        color(240, 100, 100);

Palette.pde:

public class Palette {
    Palette() {         
        palette.add(red);
        palette.add(yellow);
        palette.add(green);
        palette.add(blue);
    }
    
    ArrayList<Integer> get() {
        return this.palette;
    }
    
    private ArrayList<Integer> palette = new ArrayList<>();
} 

DrawColorSwatches.pde:

void drawColorSwatches() {      
    Palette palette = new Palette();
    ArrayList<Integer> colors = palette.get();
    float swatchSize = width / (float)colors.size();
    
    for (int i = 0; i < colors.size(); i++) {
        color c = colors.get(i);
        fill(c);
        rect(i * swatchSize, 0, swatchSize, 50);
        
        // Display HSB values
        fill(0);
        text("H: " + hue(c) + "\nS: " + saturation(c) + "\nB: " + brightness(c), 
            i * swatchSize + 5, 60);
    }
}

These constants are declared outside setup or any other function so will be executed before the setup() function. This means before the colorMode(HSB,360,100,100); statemnent so uses the default RGB color mode.

2 Likes

OK thanks, that explains a lot!

Is there a way to predict the order of initialization in processing when using multiple files? Or is everything meant to be encapsulated in class definitions or methods, to be called in the desired order?

In Processing when using multiple pde tabs the files are all concatenated into a single file and the entire code is wrapped in a Java class named after the sketch name. This Java class is then compileed and instantiated.

So the answer to the question

is both yes and no. Although we can’t predict the order the files are concatenated we can predict the order that statements are executed when a Java class is instantiated. This is why I know that the color constants are initiated before the setup function is executed.

2 Likes

So, what would be a suitable project design in order to make sure that objects are instantiated in the desired order?

Take a look in this folder ( %temp%/processing ) to see the java code that Processing is generating:

This example will generate HSB color constants (stored as RGB) to use later in desired mode:

import java.awt.Color;

// Create color constants using colorMode(HSB, 360, 100, 100) values

// These are RGB colors but you want these to represent HSB colors:
// final color red =         color(0, 100, 100);
// final color yellow =      color(60, 100, 100);

//https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/java/awt/Color.html

// This will save colorMode(HSB, 360, 100, 100) values to RGB for use later with that mode:

final Color red_hsb = Color.getHSBColor(0/360.0, 100/100.0, 100/100.0);
final int red = red_hsb.getRGB();

final Color yellow_hsb = Color.getHSBColor(60/360.0, 100/100.0, 100/100.0);
final int yellow = yellow_hsb.getRGB();

final Color green_hsb = Color.getHSBColor(120/360.0, 100/100.0, 100/100.0);
final int green = green_hsb.getRGB();

void setup()
  {
  println(g.width, g.height);  
  size(150, 150);  
  colorMode(HSB, 360, 100, 100);  
  
  println(hex(red), hex(yellow), hex(green)); 
  
  fill(red);
  circle(30, 30, 30);
  
  fill(yellow);
  circle(60, 30, 30);  
  
  fill(green);
  circle(90, 30, 30);  
  }

void draw()
  {  
  }

Reference:

:)

1 Like

There are a few PApplet members which should only be accessed when settings() or setup() are called back, not before!

Fields like width & height. And methods such as sketchPath() & color().

If we need to access color() before setup(), besides @glv’s workaround using Java’s Color class, we can replace the former w/ #RRGGBB literals:

static final color[] PALETTE = {
  #FF0000, // red
  #00FF00, // lime
  #0000FF, // blue
  #FF00FF, // fuchsia
  #00FFFF  // aqua
};

Notice my PALETTE[] array above doesn’t rely on method color() in order to populate its colors.

3 Likes

Thanks for your feedback everyone! I’m defining color constants - among other constants - in a dedicated Constants.pde file. It appears to be the least complicated solution for now, and I hope it will work from now on.