0

I am attempting to control a 240 long line of RGB pixels (ws2812b) using an artnet to dmx controller and need to generate colour gradients down the length of the line of pixels.

I had the idea of using the C# built in graphics libraries to generate the colour gradients and then extract the individual pixel values and send these to the dmx controller.

Is it possible to extract individual interpolated values from a LinearGradientBrush or a LinearGradientBrush applied to a shape (line/rectangle etc)?

Hatman
  • 21
  • 1
  • 5
gmaann
  • 39
  • 3
  • it is easy and cheap by simply drawing onto a bitmap of the desired length and height = `1`. Then use GetPixel to pull out all the colors..! See [here](http://stackoverflow.com/questions/30339553/fill-panel-with-gradient-in-three-colors/30341521?s=2|0.5508#30341521) for an example that paints stripes and [here](http://stackoverflow.com/questions/26461579/displaying-heatmap-in-datagridview-from-listlistt-in-c-sharp/26482670?s=9|0.0451#26482670) for one that extracts a list of gradient colors (Have a look at the `interpolateColors` function! Much cheaper than writing a function to do the math – TaW Nov 03 '15 at 10:43

2 Answers2

1

What you could do is let the brush draw a line on a bitmap and extract the pixels from that, but I believe that would be unnecessarily expensive and complicated. What would be better is simply lerping between the colours you want.

This can be achieved by writing a lerp method like so:

float Lerp(float from, float to, float amount)
{
    return from + amount * (to - from);
}

and using this for the R G and B values of the colors you want to lerp between. For example:

Color Lerp(Color from, Color to, float amount)
{
    return Color.FromArgb(
        (int)Lerp(from.R, to.R, amount),
        (int)Lerp(from.G, to.G, amount),
        (int)Lerp(from.B, to.B, amount));
}

I hope this helps.
~Luca

Luca_Scorpion
  • 371
  • 4
  • 15
0

Here is a function that takes a list of stop colors and returns a list of evenly interpolated colors:

List<Color> interpolateColors(List<Color> stopColors, int count)
{
    List<Color> ColorList = new List<Color>();

    using (Bitmap bmp = new Bitmap(count, 1))
    using (Graphics G = Graphics.FromImage(bmp))
    {
        Rectangle bmpCRect = new Rectangle(Point.Empty, bmp.Size);
        LinearGradientBrush br = new LinearGradientBrush
                                (bmpCRect, Color.Empty, Color.Empty, 0, false);
        ColorBlend cb = new ColorBlend();

        cb.Colors = stopColors.ToArray();
        float[]  Positions = new float[stopColors.Count];
        for (int i = 0; i < stopColors.Count; i++) 
              Positions [i] = 1f * i / (stopColors.Count-1);
        cb.Positions = Positions;
        br.InterpolationColors = cb;
        G.FillRectangle(br, bmpCRect);
        for (int i = 0; i < count; i++) ColorList.Add(bmp.GetPixel(i, 0));
        br.Dispose();
    }
    return ColorList;
}

You could call it as:

List<Color> ColorList = interpolateColors(
                        new List<Color>{Color.Red, Color.Blue, Color.Yellow}, 240);

enter image description here enter image description here

240 and 740 colors. To get all distinct colors make sure they are not too many and not too close, as the maximum number of RGB hues between two colors is 256, so the second example may hit that limit..

TaW
  • 53,122
  • 8
  • 69
  • 111