Palette Functions - AlbertGBarber/PixelSpork GitHub Wiki

Jump to Functions for:

Intro:

This page lists a series of utility functions for working with Palettes. While Palettes are fairly simple, I recommend using these functions for manipulating them, rather than doing it manually. These functions are stored under the namespace, paletteUtilsPS.

An example of using the namespace to call the getPaletteColor() function:

paletteUtilsPS::getPaletteColor( myPalette, 0); //returns the color at the 0th index in "myPalette"

While you probably won't use most of these functions directly, as they're mainly for use in effects or the Palette utility classes, the namespace includes a functions for: retrieving Palette colors, setting Palette colors, creating simple Palettes, and more.

You can also find these functions in "paletteUtilsPS.h" and "paletteUtilsPS.cpp".

Note that when getting and setting colors, Palettes wrap. So if you ask for a color at an index that is greater than the Palette's length, the code will wrap back to the start of the Palette (using mod) so that some color is always returned. This helps prevent crashes and also makes blending Palettes of different lengths together much easier. For example, if I have a Palette with 3 colors, and I ask for a 4th color, the code wraps the request back to the start of the Palette, so I'd actually get the 1st color back. If I asked for a 5th, I'd get the 2nd, etc.

Functions for Getting Colors from Palettes:

These functions return a color from a Palette. While this includes just getting the plain color from a certain Palette index, there are also functions for getting colors that are a blend between two Palette colors, choosing a color at random, etc.

  • CRGB getPaletteColor(palettePS &palette, uint8_t index);
    

    Returns the color in the Palette at the specified index. Note that Palettes wrap, see the intro for more.

  • CRGB *getColorPtr(palettePS &palette, uint8_t index); 
    

    Returns a pointer to the Palette color at the specified index. Useful for binding an external color to a Palette color, such as the background color of an effect. You could then blend the Palette using one of the Palette utility classes, and the external color would change too as they are considered the same. Background binding example: yourEffect.bgColor = paletteUtilsPS::getColorPtr(yourPalette, colorIndex);

  • CRGB getShuffleColor(palettePS &palette, CRGB &currentPaletteVal);
    

    Returns a random color from the Palette that is different from the current color you're using, currentPaletteVal. Ex, if my effect is currently using Red from my Palette, it can ask this function for a random Palette color that will not be Red. Note that if your Palette has repeated colors, it is possible to get the same color back.

  • CRGB getBlendedPaletteColor(palettePS &palette, uint8_t startIndex, uint8_t endIndex, uint8_t step, uint8_t totalSteps);
    

    Returns the blended result of two Palette colors. startIndex and endIndex are the starting and ending Palette color indexes. step is the blend amount out of totalSteps. So a blend at step 5 out of 10 totalSteps would be 50% blended towards the endIndex color.

  • CRGB getPaletteGradColor(palettePS &palette, uint16_t step, uint16_t offset, uint16_t totalSteps);
    

    Returns a blended color from the whole Palette, treating the Palette as one long gradient between all its colors. totalSteps is the length of the whole gradient, with step marking the slice of the gradient you want. offset increments the step value and can be used for shift the whole gradient. The number of gradient steps between each color will be totalSteps/palette.length.

  • CRGB getPaletteGradColor(palettePS &palette, uint16_t step, uint16_t offset, uint16_t totalSteps, uint16_t gradLength);
    

    Exactly the same as the above getPaletteGradColor(), but takes the number of steps between each color as an argument: gradLength. This slightly speeds up execution when fetching multiple gradient colors because you can pre-calculate gradLength, rather than forcing the function to re-do it with each call. gradLength should always be totalSteps/palette.length.

Functions for Changing Palettes:

These functions focus on changing a Palette, going from changing a single Palette color, to shuffling or randomizing the whole Palette.

  • void setColor(palettePS &palette, CRGB color, uint8_t index);
    

    Changes the Palette color at the index to the passed-in color.

  • void randomizeCol(palettePS &palette, uint8_t index);
    

    Sets the color at the index to a random color.

  • void randomize(palettePS &palette, bool comp = false);
    

    Sets all the colors in a Palette to random colors. Can be used with the comp argument omitted. If comp is true, then the function will try to pick complimentary colors for the Palette, starting with a random hue, using a limited random saturation value. This allows you to make random triad, tetrad, and complimentary Palettes. ie a Palette of length 3, would make a triad complimentary Palette.

  • void shuffle(palettePS &palette, uint8_t *indexOrder = nullptr);
    

    Randomizes the order of colors in a palette. Note that it does not check against the current order, so it's possible to get the same palette order back. The likely-hood of this is 1/(palette.length!), ie 1/3! => 1/6 for a palette length of 3. The function also includes an optional indexOrder array input. It is set to match the shuffled index order, allowing you to track the palette changes over time without checking colors.

    For example, for a palette of 3 colors, if the shuffled palette only swaps the last to colors, the indexOrder would be [0, 2, 1]. NOTE that indexOrder's length should be equal to palette.length, and it should be pre-filled with the palette indexes (ie for a palette of length 3, it would be [0, 1, 2]).

  • void shuffleSet(paletteSetPS &paletteSet, uint8_t *indexOrder = nullptr);
    

    Randomizes the order of palettes in a palette set (an array of palettes). Behaves and has the same quirks as the above shuffle() function, but applied to whole palettes instead of palette colors.

  • void reverse(palettePS &palette);
    

    Reverses the order of colors in a palette.

Functions for Quickly Creating Palettes:

These functions can be used to quickly create new Palettes. Note that the Palettes are created dynamically (unless otherwise noted), so you must free them after you are done with them by calling free( youPalette.paletteArr );. This frees the memory for the Palette's color array to the rest of the program. Warning!! Repeatedly creating and freeing Palettes may lead to memory fragmentation! (See the previous link for info).

To use these functions you create an empty Palette and then call one of the functions to fill it in:

Example:

palettePS myPal = {0, nullptr}; //Create an empty Palette.
myPal = paletteUtilsPS::makeSingleColorPalette(CRGB::Red); //Makes a single color Palette, and copies it into myPal

Functions:

  • palettePS makeSingleColorPalette(CRGB color);
    

    Returns a single entry Palette with a single color.

  • palettePS makeRandomPalette(uint8_t length, bool comp = false);
    

    Returns a Palette with a random set of colors of size length. Can be used with the comp argument omitted. If comp is true, then the function will try to pick complimentary colors for the Palette, starting with a random hue, with a limited random saturation value. This allows you to make random triad, tetrad, and complimentary Palettes. ie a Palette of length 3, would make a triad complimentary Palette.

  • palettePS makeCompPalette(uint8_t length, uint8_t baseHue, uint8_t sat, uint8_t val);
    

    Returns a Palette with a set of complimentary colors using baseHue as the starting hue. length sets the number of colors in the Palette, allowing you to quickly generate triad, tetrad, and complimentary Palettes. Note that the colors are HSV based. sat and val adjust the saturation and value of the resulting Palette colors.

  • palettePS splitPalettePtr(palettePS &inputPalette, uint8_t startIndex, uint8_t splitLength);
    

    Returns a palette that is a subsection of an input palette. The subsection starts at the startIndex of the input palette, and is splitLength colors long. So the ending color index is startIndex + (splitLength - 1) (because we include the start index color). Note that the output palette re-uses the pointer to the input palette's color array, but offset by the startIndex. This means that any changes to the original palette will be reflected in the split palette automatically. This is great for blending palettes, but if you ever change the original palette's color array pointer, you must update the split palette (most easily by calling the split function again)!

    Examples:

    • Ex 1: I have an input palette with 5 colors, I want a sub-palette with the last 3 colors.

      I would do splitPalette( inputPalette, 2, 3 ); to capture the input palette color indexes 2, 3, 4 (ie the last 3 colors).

    • EX 2: I want to capture only the first color in the input palette.

      I would do splitPalette( inputPalette, 0, 1 );