1
votes

I'd like to ask if it's possible to transform between RGB and one continuous color value (like in float [0..1] or Integer [0..255]) that represents a color range.

E.g.: I have a continous color range like a rainbow:

Red - Orange - Yellow - Green - Blue - Indigo - Violet

-> represented with 0~1 or 0~255 (or whatever range)

And now I want to transform the value e.g. (0.5 = green) to an equal RGB value ([0,1,0]?). Is that possible with a transfer function (back and forward)? Maybe in Python?

3

3 Answers

3
votes

The whole reason that RGB requires 3 numbers is because it is essentially a 3D space. You would be trying to squeeze 3 continuous number lines into 1! You'd have to choose a scale, have a play around like below to see which colour blend through you like... (code written in VBA but easily portable)

For i = 1 To 255   
    ' Scale with no red, increase and decrease blue and green respectively
    Range("a" & i).Interior.Color = RGB(0, i, 255 - i)
    ' Use a MOD function to keep the values between 0 and 255
    ' note this can cause some abrupt changes in your scale
    Range("b" & i).Interior.Color = RGB(128 + i Mod 255, i, 255 - i)
    ' You can increase and decrease different RGB values for desired result
    Range("c" & i).Interior.Color = RGB((255 - i) Mod 255, (0 + i) Mod 255, i)    
Next i

Output (columns made into rows for better viewing here):

Colour bands

So to go from RGB to a 1D scale (like those above) you would just have i as your single variable, you could store a lookup if you wanted or create a function which does as each line above does, creating the colour from a single value of i.

Now going back from this 1D scale to a 3D scale is technically impossible. You have lost the extra information you need. However, if you knew your mapping function to create the scale, you can simply get each RGB value by its respective input.

Hope this helps.

1
votes

The simplest way is simply to add up the RGB while weighting each component. Doing so will give you a range 0-16,777,215. Eg:

RGB Tuple = Hex Value = Decimal
0,0,0 = 0x000000 = 0
255,255,255 = 0xFFFFFF = 16777215

Here's a online calculator that will convert any individual color: https://www.shodor.org/stella2java/rgbint.html

Code for hex converters in any given language will be all over the google. :)

You can use any number space you like (eg 0-1 or whatever) and go back and forth as much as you want, so long as your chosen number space holds all of those 16.7+ million unique colors.

If you compress the number space, you'd be losing some colors (as the first poster explained).

0
votes

This function will do the transfer in one direction (single value to rgb)...

f(x,i) = max(0, min(1, 3*abs(1 - 2*(( x - i/3 ) mod 2)) - 1))

...if you define your rgb values as

{ f(x,0) , f(x,1) , f(x,2) }

It starts at red (for x = 0) and linearly interpolates between yellow (x = 1/6), green (x = 2/6), cyan (x = 3/6), blue (x = 4/6), magenta (x = 5/6), ending full cycle at red (x = 1) again.