Color Fading Algorithm

Color fading algorithm?

Based on this example, the Queue<Color> below cycles from Color.green to Color.blue and back to Color.green again in N = 32 steps. Note that Color.green is numerically less than Color.blue in the HSB model. See also this related example using HSB.

Sample Image

public Flash(JComponent component) {
this.component = component;
float gHue = Color.RGBtoHSB(0, 1, 0, null)[0];
float bHue = Color.RGBtoHSB(0, 0, 1, null)[0];
for (int i = 0; i < N; i++) {
clut.add(Color.getHSBColor(gHue + (i * (bHue - gHue) / N), 1, 1));
}
for (int i = 0; i < N; i++) {
clut.add(Color.getHSBColor(bHue - (i * (bHue - gHue) / N), 1, 1));
}
}

Color Fading Algorithm not working?

The only problem is: the more fading transition objects I add in, the faster they all go

private static float time = 0;

You are using a static variable for the time. This variable is shared by all instances of the ColorFade class. So each fading objects updates the same variable.

Don't use a static variable (just get rid of the static keyword). Each fading object needs its own "time" variable.

private float time = 0;

I also question if the firstColor variable should be static.

Algorithm: How do I fade from Red to Green via Yellow using RGB values?

The RGB values for the colors:

  • Red 255, 0, 0
  • Yellow 255, 255, 0
  • Green 0, 255, 0

Between Red and Yellow, equally space your additions to the green channel until it reaches 255. Between Yellow and Green, equally space your subtractions from the red channel.

How to fade color

There are a bunch of ways to do this. How you choose to do it will depend on whether you value speed and simplicity or perceptual uniformity. If you need it to be truly uniform you will need to define you RGB colors with a color profile and you'll need the primaries of the profile so you can convert to XYZ and then to LAB where you can manipulate the L channel.

Most of the time you don't need to do that and you can instead use a simple HSB model like Photoshop does in the info palette.

To do this you simply imagine a line between your RGB point and the white point in 3D space and move your color along that line. In practical terms you can just create a parametric equation for that line and move the parameter.

import numpy as np

def lighter(color, percent):
'''assumes color is rgb between (0, 0, 0) and (255, 255, 255)'''
color = np.array(color)
white = np.array([255, 255, 255])
vector = white-color
return color + vector * percent

A percentage of 0.0 will return the same color and 1.0 will return white. Everything between will be a lighter shade of the same hue. This should give you results that agree with Photoshop's HSB implementation, but will be device dependent and may not be perfectly uniform.

If you have RGB [200, 100, 50] and put in a percentage of .50 it should return RGB[ 227.5 177.5 152.5] Photoshop reports both as a hue of 20º.

It is not hard to do this without numpy, but the element wise operations are convenient.

Edit based on comment:

I'm not suggesting you do this unless you know you really need to do it the hard way. But if you want to convert to LAB you can without too much trouble. The most important thing is that you need to know what color space your RGB numbers are in to begin with or you need to make some assumptions about their meaning. Since sRGB is pretty standard on the web, I'll assume that here.

The conversions aren't that difficult, but it's easy to make mistakes. Happily, there's a pretty nice colormath module with good documentation: https://github.com/gtaylor/python-colormath

Using that you can convert between sRGB and LAB like this:

from colormath.color_objects import sRGBColor, LabColor
from colormath.color_conversions import convert_color

sRGB = sRGBColor(126, 126, 126, is_upscaled=True) # or between [0, 1] with out is_upscaled
lab = convert_color(sRGB, LabColor)

lab now is a color with a Luminance channel lab.lab_l which you can move up or down between black(0) and white(100). This should be more perceptually uniform than HSB (but, depending on your application, maybe not enough to warrant the work).

You can simply change lab_l and then convert back:

lab.lab_l = 80
new_sRGB = convert_color(lab, color_objects.sRGBColor).get_upscaled_value_tuple()

new_sRGB is now [198, 198, 198]. colormath took care of the illuminant and gamma issues for you.

Python - RGB LED Color Fading

It sounds like you want to start at colorFrom, and gradually step
along a straight line until you reach colorTo.

What this code does is start at colorFrom, then increment the current
color as if you were stepping from black to colorTo.

Hard to be sure without the full code, but it looks like you should
replace this:

step_R = int(colorTo[0]) / steps
step_G = int(colorTo[1]) / steps
step_B = int(colorTo[2]) / steps

with this:

step_R = (colorTo[0] - colorFrom[0]) / steps
step_G = (colorTo[1] - colorFrom[1]) / steps
step_B = (colorTo[2] - colorFrom[2]) / steps

Edit: And, as jasonharper pointed out, you may be doing integer division. Not clear what your types are. If you're using Python 2, / is integer division. In Python 3, it's floating point.

What's the correct math to fade a color?

Here's an idea that might work.

Don't do the math in Red-Green-Blue space. Instead treat your colour as having three components:

  • Hue (is it red, orange, yellow, green, blue, violet, etc),
  • Saturation (how intense is the color?)
  • Value (how much blackness is in the color?)

There are algorithms for converting from RGB to HSV; look them up. This is a good place to start:

http://en.wikipedia.org/wiki/HSL_and_HSV

Now when you are fading from one color to the other, take steps along the HSV axes, not along the RGB axes.



Related Topics



Leave a reply



Submit