XEN-L001: Color library


#1

Many hardware projects involve some light effects. To achieve the effects various colorful LEDs and LED strips are widely used. Color is not a trivial scalar. Several notations exist to define a color. For example RGB, HSV, and HSL. XOD should provide a standard library to hold and transfer color values so that library authors don’t reinvent color-related nodes again and again.

Read on: https://github.com/xodio/xod-xens/tree/master/XEN-L001


#2

Are there details that could be added for format-hex? For example, is the output really RGB in the format “RRGGBB”? If not, how are the values determined?

If it is RGB, a corresponding function to convert to color would probably be useful. For people who want a specific color, having to convert 0-255 to 0-1 is going to be a pain. You need to keep node to convert 0-1 range to color for those who want to use POTs or other built-ins to select color.


#3

Thanks for the feedback!

Yes, format-hex just outputs a six-character string without any possible adjustment. It exists as a tool to quickly observe a result as text (for watch, LCD, serial) created by, say, potentiometers. A final resort for human-to-human and device-to-human communication. That’s it.

Do you mean that the [0; 1] range is so uncommon for colors that we also should provide nodes to pack/unpack color from/to three 0-255 values? I tend to agree actually, but, but, but… Isn’t the hex form (#fd7412) is even more widespread? Regardless of what’s more popular (0-255 triple or hex), how does it matter? Are xoders going to find a color in the internet or graphical editor and then try to output it on a LED strip?

I wonder what scenarios do you see especially related to the educational process.


#4

I think the hex form is usually just RGB values concatenated together (2 hex digits allowing for 0-255 for each color), so the two formats over-lap somewhat.

We could probably get away with a node that just maps 3 input values to 3 output values 0-255 -> 0-1; input could be decimal or hex. These could then be fed to color node (or color node included inside this mapping node). Maybe there wouldn’t be much demand for this & documentation could just suggest using map node (but that creates a lot of extra pins for a simple mapping…). A hex string input node could split string into 3 values & feed to this mapping node…

I doubt many XODers will be looking to exactly replicate some other color, but they might be trying to convert existing code, or see a color they want to get close to. 0-1 range makes sense from a XOD perspective since it is an internal standard, but there is no easy way to convert to “real world” representations of color (or even to feed-back your format-hex values back into XOD code). Also, keeping parallel with color-hsl, to-hsl, color(-rgb?), to-rgb for hex node(s) makes sense.


#5

OK, got it.

What do you think, would addition of the following node make the lib unarguably better?

color-rgb-bytes

Constructs a color value from red, green, and blue components expressed as byte values. Use decimal (0d to 255d) or hexadecimal (00h to FFh) byte literals. For example, if a graphical editor shows a blue as “#287ec9” or “rgb(40, 126, 201)” use the following literals for R/G/B: 28h/7Eh/C9h or 40d/126d/201d.

Dir Pin Type Default Description
in R byte 0d Red
in G byte 0d Green
in B byte 0d Blue
out color

#6

That would be perfect.

Should color be renamed color-rgb for consistency?

(The following very intentionally uses soft words like maybe, consider, perhaps. Are you looking to provide just what is needed, or a complete & consistent library?)

Also for consistency, maybe consider changing format-hex to to-hex & maybe adding color-hex (just a wrapper to split string & pass to color-rgb-bytes). More for consistency/convenience than because it is really needed…


#7

I’m looking for a balance. New nodes might be added later, but the initial set should form a strong basis. Perhaps it is a good idea to postpone the addition of nodes that are too vague or controversial in the current moment. The real use cases can show an optimal solution later.

Should color be renamed color-rgb for consistency?

Well, now we have color, color-hsl, and color-rgb-bytes. Indeed, inconsistent. But we “cannot” rename color because it defines the type name. Otherwise, the type will be color-rgb everywhere. But we can hide the color node by making it a utility. Then we can provide the color-rgb node for constructing with [0; 1] range values. Makes sense, thank you.

maybe consider changing format-hex to to-hex

Format is a verb commonly used for converting something to its string representation. We have format-number, format-timestamp, etc :thinking: So the consistent name should even be format-color-hex. But isn’t it too long? If we are thinking about HEX as of an alternative form of color, then yes to-hex matches to-rgb and to-hsl perfectly. I’m not sure how should we think of HEX.

maybe adding color-hex

This opens many questions about input validity. Are the following should be considered valid?

  • "#ffd400"
  • "fd0"
  • " FFD400 "

What should we output for an incorrect input like "Hello"? I think some kind of universal approach should be established to make nodes that parse things (numbers, timestamps, colors, etc). They are by definition can be supplied with invalid input.

Because of these questions, perhaps, we should skip the color-hex for now.


#8

Sounds good. I just figured these were questions that would be easier to address now than after library was created & people were using it.


#9

The Adafruit NeoPixel library does exactly this: packs 3 bytes into a long. And has a static method to do that. Several methods that need a RGB take either r,g,b, or one of those packed-longs. One function only takes a packed-long (fill()).

A color value can be stored as three bytes:

Also, the NeoPixel library deals in RGBW, where there is a specific value for White (which is a distinct led in some NeoPixels). That can also be packed into the uint32.

Use decimal (0d to 255d) or hexadecimal (00h to FFh) byte literals.

HTML/CSS colors are well known, so the 2 character hex seems like a useful thing, as well as the html style “#A0274C” style. Are there very many 2byte-per-color devices?

Each component should be in the range [0, 1].

This echos the analog-read, and pwm out. Which is nice. And, covers the 1-byte-per-pixel vs. 2-byte-per-pixel possibilities. But, is a pain if you want to work in 0-255 ranges.

color-hsl … hsv etc

Is it common enough to want it? Wait till we need it? A note in the “color library” to request it? Don’t forget CMYK, lest ink/paint/print people get annoyed! Or NTSC & PAL.

I work with an artist that uses LEDs extensively to achieve some interesting dynamic color effects. He originally thought in RGB, but has more recently been working in HSV (to achieve constant value). It seems that different places have different ideas of what HSV means. Apparently Excel has a … different idea (I think it’s actually HSL?). Then, of course, there’s all the human-perceptual-system-corrected-color-spaces, e.g. CIE color-spaces. Which he’d really rather use, because that’s actually what he wants (but lots of math, so he did his own crude approximation). Wikipedia has an article about that.

I also work with an art-college, and the students like things like “warm” and “cool” and “white-point”.


#10

Yeah. I did not want to replace 0-255 range nodes with 0-1 range nodes. Ideally you would have both. Use 0-1 ranges if you are using POTs or similar to control; use 0-255 range if you want to specify a specific color. There might be several 0-255 range nodes for RGB, hex, etc. There probably only needs to be one 0-1 range node for RGB.

I guess someone who wants to generate HSV output from POTs would want a 0-1 range HSV node, but it can be simulated using map nodes. Most beginners who would want 0-1 range node are probably working with RGB. An RGB LED is pretty standard for beginner kits. On the other hand, beginners trying to control a single RGB LED with pots probably won’t be using this library…


#11

Hmm I missed this one…
You guys talking about something like this?
bradzilla84/color-rgb-hsl

The color block can put out multiple types at the same time(RGB,HEX ect…) it is up the individual implementation as to which value you pull. There is also a HSL block that does a simple conversion back to RGB values that can then be piped through the colour block.
I am in the process of upgrading my TFT LCD libraries to all use the same block for colour.
You can see an example of it’s use in
bradzilla84/color-tft-lcd-driver-mcufriend-kbv

Was I heading in the right direction?
You can use 0.0-1.0 or you can use 0-255 the block will scale automatically.


#12

The HSL/HSV model (minor difference) are very useful to produce pure colors: the most vibrant colors a particular LED device can produce. So I think they are quite relevant much more than CMYK which is a subtractive model used to make initially white objects darker (print on paper). We use HSL in our experiments often. One of the projects demonstrating it will be published in a week. HSL is cool to express a color: imagine a LED strip running through the rainbow with a slider adjustment; I think it is even more natural than RGB which is absolutely dominant, but nevertheless is quite technical.

From what I see in the discussion now, it is better to reserve an extra byte beside the r, g, b because in many scenarios it is used somehow: white in Neopixels, transparency on smart displays, etc.