Question

I want to create a Snapshot of the Canvas Area in my Application. I'm using Visual brush to get the Snapshot and saving the same using PngEncoder. But the resulting PNG is just a empty black image. I'm not sure the issue is with the BitmapSource created or the PNGEncoder issue. Here is the code I'm using to obtain the same.

public void ConvertToBitmapSource(UIElement element)
{
    var target = new RenderTargetBitmap((int)(element.RenderSize.Width), (int)(element.RenderSize.Height), 96, 96, PixelFormats.Pbgra32);
    var brush = new VisualBrush(element);

    var visual = new DrawingVisual();
    var drawingContext = visual.RenderOpen();


    drawingContext.DrawRectangle(brush, null, new Rect(new Point(0, 0),
    new Point(element.RenderSize.Width, element.RenderSize.Height)));

    drawingContext.Close();

    target.Render(visual);

    PngBitmapEncoder encoder = new PngBitmapEncoder();
    BitmapFrame outputFrame = BitmapFrame.Create(target);
    encoder.Frames.Add(outputFrame);
    using (FileStream file = File.OpenWrite("TestImage.png"))
    {
         encoder.Save(file);
    }

}   
Était-ce utile?

La solution

Not sure why exactly your code isn't working. This works:

public void WriteToPng(UIElement element, string filename)
{
    var rect = new Rect(element.RenderSize);
    var visual = new DrawingVisual();

    using (var dc = visual.RenderOpen())
    {
        dc.DrawRectangle(new VisualBrush(element), null, rect);
    }

    var bitmap = new RenderTargetBitmap(
        (int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default);
    bitmap.Render(visual);

    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bitmap));

    using (var file = File.OpenWrite(filename))
    {
        encoder.Save(file);
    }
}

Autres conseils

Thank you both for the question and the answer.

For the benefit of the others looking for the same answer

I found that Clemens way leaves a black band in the image with the image shifted either down or right. As if it was not rendering the element at the correct position in the bitmap.

So I had to use the VisualBrush as Amar suggested.

Here is the code that worked for me:

    RenderTargetBitmap RenderVisual(UIElement elt)
    {
        PresentationSource source = PresentationSource.FromVisual(elt);
        RenderTargetBitmap rtb = new RenderTargetBitmap((int)elt.RenderSize.Width,   
              (int)elt.RenderSize.Height, 96, 96, PixelFormats.Default);

        VisualBrush sourceBrush = new VisualBrush(elt);
        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();
        using (drawingContext)
        {
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), 
                  new Point(elt.RenderSize.Width, elt.RenderSize.Height)));
        }
        rtb.Render(drawingVisual);

        return rtb;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top