How to get the value of the color in some position of a LinearGradientBrush?

Hi everybody,I have a problem about LinearGradientBrush.

Here's the code:

<Canvas Name="MainCanvas" Height="20" Width="200" Margin="0,0,0,0">
<Rectangle Name="rectLegend" Width="200" Height="10"><Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="white" Offset="0" />

<GradientStop Color="red" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Canvas>

Now i want to get the value of the color at some position of the Rectangle( or LinearGradientBrush ).Position means (x,y) or 50% .

How can i get it Who can help me

Thanks in advance.



Answer this question

How to get the value of the color in some position of a LinearGradientBrush?

  • um_au

    I finally make them work:-)

    and i find out that why i always get black color.

    It's because i tried to read the value before the rectangle was drawn onto the screen.

    I thought i can read the value the moment after i did rect.fill=... but it's not true.

    Thank you David!


  • bismarck

    You actually can get the values before the rectangle has been drawn, but you have to manually measure, arrange, and update the layout of the rectangle since normally these are done when it's rendered, and without them the rectangle has no size.

    Here's the code to do it:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Controls;
    using System.Windows.Shapes;


    namespace ConsoleApplication1
    {
    class Program
    {
    [STAThread]
    static void Main(string[] args)
    {
    Window w = new Window();

    Grid g = new Grid();

    DockPanel dp = new DockPanel();
    w.Content = dp;

    Rectangle r = new Rectangle();
    r.Width = 50;
    r.Height = 50;
    r.Fill = new LinearGradientBrush(Colors.CornflowerBlue, Colors.PeachPuff, 13.37);

    g.Children.Add(r);
    g.Width = 50;
    g.Height = 50;

    DockPanel.SetDock(g, Dock.Bottom);

    dp.Children.Add(g);

    TextBox tb = new TextBox();

    ScrollViewer sv = new ScrollViewer();
    sv.Content = tb;

    tb.TextWrapping = TextWrapping.Wrap;

    dp.Children.Add(sv);


    r.Measure(new Size(50, 50));
    r.Arrange(new Rect(new Size(50, 50)));
    r.UpdateLayout();

    RenderTargetBitmap rtb = new RenderTargetBitmap((int)r.ActualWidth, (int)r.ActualHeight, 96.0, 96.0, PixelFormats.Pbgra32);
    rtb.Render(r);

    byte[] pixel_data = new byte[(int)(r.ActualWidth * r.ActualHeight) * 4];

    rtb.CopyPixels(pixel_data, (int)(r.ActualWidth) * 4, 0);

    tb.Text += "Colors in pbgra32 format:\n";
    int n = 0;
    while (n < pixel_data.Length) {
    tb.Text += "(" + pixel_data[n++] + " " + pixel_data[n++] + " " + pixel_data[n++] + " " + pixel_data[n++] + ") ";
    }

    w.Show();


    Application app = new Application();
    app.Run();
    }
    }
    }

    David

  • rhs_fss

    Thanks David:)

    I fill a rectangle with the LinearGradientBrush, and then render the rectangle into a RenderTargetBitmap. I believe there is a way to read the value (maybe it's CopyPixels ) , but i cannot find it.

    Would you please give me a piece of sample code

    Thanks again!


  • Phalanx

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Controls;
    using System.Windows.Shapes;


    namespace ConsoleApplication1
    {
    class Program
    {
    [STAThread]
    static void Main(string[] args)
    {
    Window w = new Window();

    Canvas c = new Canvas();
    w.Content = c;

    Rectangle r = new Rectangle();
    r.Width = 50;
    r.Height = 50;
    r.Fill = new LinearGradientBrush(Colors.CornflowerBlue, Colors.PeachPuff, 13.37);
    c.Children.Add(r);
    w.Show();

    RenderTargetBitmap rtb = new RenderTargetBitmap((int) r.ActualWidth, (int) r.ActualHeight, 96.0, 96.0, PixelFormats.Pbgra32);
    rtb.Render(r);

    byte[] pixel_data = new byte[(int)(r.ActualWidth * r.ActualHeight) * 4];

    rtb.CopyPixels(pixel_data, (int)(r.ActualWidth) * 4, 0);

    Console.WriteLine("Colors in pbgra32 format:");
    int n = 0;
    while (n < pixel_data.Length) {
    Console.WriteLine("(" + pixel_data[n++] + " " + pixel_data[n++] + " " + pixel_data[n++] + " " + pixel_data[n++] + ")");
    }

    Application app = new Application();
    app.Run();
    }
    }
    }

    Hope that helps,
    David

  • Gun

    Yes I want to read the value.

    And I think the way to set and the way to read are always the same.


  • moviejunkie

    So you want to be able to read the value at some arbitrary position (x,y) of your rectangle Or are you saying you want to set the color at an arbitrary position (x,y)

    David

  • blue3952

    and Pbgra32 is the only format that works with rtb afaik.

  • tash12457769

    It works!

    But when i add the rectangle into a DockPanel but not a Canvas, the values in pixel_data are all 0. Is there any differences between DockPanel and Canvas in this programme

    and when i change the PixelFormats(into Rgb24 or others ), the rtb doesn't work. Why is it

    Thank you Davied,the codes you give do work well :-)


  • PSuo

    You need to nest the rectangle within another control so that its origin still maps to the control's upper left corner. Then you can set the Dock property on the outer control.

    Here's some code:


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Controls;
    using System.Windows.Shapes;


    namespace ConsoleApplication1
    {
    class Program
    {
    [STAThread]
    static void Main(string[] args)
    {
    Window w = new Window();

    Grid g = new Grid();

    DockPanel dp = new DockPanel();
    w.Content = dp;

    Rectangle r = new Rectangle();
    r.Width = 50;
    r.Height = 50;
    r.Fill = new LinearGradientBrush(Colors.CornflowerBlue, Colors.PeachPuff, 13.37);

    g.Children.Add(r);
    g.Width = 50;
    g.Height = 50;

    DockPanel.SetDock(g, Dock.Bottom);

    dp.Children.Add(g);

    TextBox tb = new TextBox();

    ScrollViewer sv = new ScrollViewer();
    sv.Content = tb;

    tb.TextWrapping = TextWrapping.Wrap;

    dp.Children.Add(sv);

    w.Show();

    RenderTargetBitmap rtb = new RenderTargetBitmap((int) r.ActualWidth, (int) r.ActualHeight, 96.0, 96.0, PixelFormats.Pbgra32);
    rtb.Render(r);

    byte[] pixel_data = new byte[(int)(r.ActualWidth * r.ActualHeight) * 4];

    rtb.CopyPixels(pixel_data, (int)(r.ActualWidth) * 4, 0);

    tb.Text += "Colors in pbgra32 format:\n";
    int n = 0;
    while (n < pixel_data.Length) {
    tb.Text +="(" + pixel_data[n++] + " " + pixel_data[n++] + " " + pixel_data[n++] + " " + pixel_data[n++] + ") ";
    }

    Application app = new Application();
    app.Run();
    }
    }
    }


    David

  • Michael1138

    You could render the gradient into a RenderTargetBitmap and then read out the value corresponding to the position in question. Be aware that content rendered into an RTB is rendered without any hardware acceleration, so it's not going to be super fast.

    David

  • John Emmanuel - MSFT

    These days i tried to find the algorithm of how does LinearGradientBrush work. I found one. i'm not sure it's the current one LinearGradientBrush use, but it works well.

    Consider there is a cube (from (0,0,0) to (1,1,1)), so color(255,255,255) is (1,1,1), erery color value is a point in the cube.

    The Gradient from colorA(r1,g1,b1) to colorB(r2,g2,b2) is just the line from pointA to pointB in the cube. and so it's easy to get value in some position from colorA to colorB using Vector3D operation.

    Of course i didn't consider the alpha component value.

    I'm not sure what i say is what i want to express, because i donnot use english in my daily life:)


  • How to get the value of the color in some position of a LinearGradientBrush?