Generate BitmapSource from UIElement

Joel picture Joel · May 6, 2009 · Viewed 7.4k times · Source

I am attempting to generate a BitmapFrame that is based on a UIElement. Here is my function:

private BitmapFrame RenderToBitmap2()
{
    RenderTargetBitmap renderBitmap = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32);

    DrawingVisual drawingVisual = new DrawingVisual();
    DrawingContext drawingContext = drawingVisual.RenderOpen();
    VisualBrush aVisualBrush = new VisualBrush(GenerateTestStackPanel());
    drawingContext.DrawRectangle(aVisualBrush, new Pen(Brushes.Green, 2), new Rect(new Size(150, 150)));

    drawingContext.Close();

    renderBitmap.Render(drawingVisual);

    return BitmapFrame.Create(renderBitmap);
}

For testing and debugging purposes, I am using an additional function that creates a simple StackFrame that should create a valid visual element that can be represented:

private StackPanel GenerateTestStackPanel()
{
    // Create a red Ellipse.
    Ellipse myEllipse = new Ellipse();

    myEllipse.Fill = Brushes.Green;
    myEllipse.StrokeThickness = 2;
    myEllipse.Stroke = Brushes.Black;

    // Set the width and height of the Ellipse.
    myEllipse.Width = 200;
    myEllipse.Height = 200;
    // Add the Ellipse to the StackPanel.
    StackPanel myStackPanel = new StackPanel();
    myStackPanel.Children.Add(myEllipse);
    return myStackPanel;
}

For some reason, the VisualBrush is not being rendered in the DrawRetangle(...) function. I can see the green border but nothing else. In addition, if I swap out the VisualBrush with a standard brush, it works great:

drawingContext.DrawRectangle(Brushes.Plum, new Pen(Brushes.Green, 2), new Rect(new Size(150, 150)));

Thanks in advance!

Answer

discorax picture discorax · Aug 19, 2009

Take a look at this for an alternate way to create a BitmapSource from a UIElement:

MSDN Thread

I have also been trying to get the VisualBrush to work without any luck which brought me to this thread.

public static BitmapSource CreateBitmapSourceFromVisual(
    Double width,
    Double height,
    Visual visualToRender,
    Boolean undoTransformation)
    {
        if (visualToRender == null)
        {
            return null;
        }
        RenderTargetBitmap bmp = new RenderTargetBitmap((Int32)Math.Ceiling(width),
            (Int32)Math.Ceiling(height), 96, 96, PixelFormats.Pbgra32);

        if (undoTransformation)
        {
            DrawingVisual dv = new DrawingVisual();
            using (DrawingContext dc = dv.RenderOpen())
            {
                VisualBrush vb = new VisualBrush(visualToRender);
                dc.DrawRectangle(vb, null, new Rect(new Point(), new Size(width, height)));
            }
            bmp.Render(dv);
        }
        else
        {
            bmp.Render(visualToRender);
        }
      return bmp;
    }