将WPF渲染为PNG会生成空白图像

时间:2019-07-17 07:52:06

标签: c# wpf

我正在尝试使用WPF(而不是旧的GDI API)将图形呈现为PNG,结果始终为空白。

我正在编写一个小程序,该程序将生成仓库周围到各种物品的图像路线。我将WPF API用于绘图,而不是使用旧的GDI API,因为图像既需要保存到磁盘,又需要在WPF应用程序中显示。问题在于,它生成的所有png文件目前都是黑色的。

为了缩小问题的范围并证明绘制地图的代码不是问题,我制定了一种最小的测试方法,应仅在黑色背景上绘制一个红色圆圈。但是结果仍然是完全黑的。

    [TestMethod]
    public void DrawingTest()
    {
        //define the dimensions of the test image
        int width = 100;
        int height = 100;
        int dpi = 100;

        //define where the image should be saved
        var path = @"C:\temp\DrawingTest.png";

        //create a bitmap to render the image into
        RenderTargetBitmap bitmap = new RenderTargetBitmap(
                    width, height, dpi, dpi, PixelFormats.Default);

        //create a drawing context to draw the image onto
        DrawingVisual drawingVisual = new DrawingVisual();
        using (DrawingContext canvas = drawingVisual.RenderOpen())
        {
            //draw a circle  
            canvas.DrawEllipse(Brushes.Red, new Pen(Brushes.Red, 1), new System.Windows.Point(50, 50), 50, 50);

            //render the image into a bitmap
            bitmap.Render(drawingVisual);
        }

        //create the file encoder
        var encoder = new PngBitmapEncoder();
        //encode the bitmap in PNG format
        encoder.Frames.Clear();
        encoder.Frames.Add(BitmapFrame.Create(bitmap));

        //make sure that the file can be saved in this location
        var directory = System.IO.Path.GetDirectoryName(path);
        if (!System.IO.Directory.Exists(directory))
            System.IO.Directory.CreateDirectory(directory);
        if (System.IO.File.Exists(path))
            System.IO.File.Delete(path);

        //save the map to file
        using (var stream = System.IO.File.Create(path))
            encoder.Save(stream);
    }

该测试方法运行无任何错误,并在我期望的位置生成了png文件。但是,此文件只是一个黑色正方形,而不是我期望的黑色正方形中的红色圆圈。谁能告诉我为什么它只是渲染黑色图像,我能做些什么使其显示红色圆圈。

1 个答案:

答案 0 :(得分:0)

在DrawingContext关闭后,您必须调用bitmap.Render(drawingVisual)

摘自DrawingContext.Close的评论:

  

DrawingContext必须先关闭,然后才能呈现其内容...

因此,只需将“渲染”调用移到using块之外:

using (DrawingContext dc = drawingVisual.RenderOpen())
{
    dc.DrawEllipse(Brushes.Red, new Pen(Brushes.Red, 1),
                   new System.Windows.Point(50, 50), 50, 50);
}

bitmap.Render(drawingVisual);

除此之外,红色的笔似乎是多余的,因为圆圈已经被红色填充了。所以应该没问题:

dc.DrawEllipse(Brushes.Red, null, new System.Windows.Point(50, 50), 50, 50);

还要确保创建DPI值为96的位图,该值对应于WPF设备无关的单位。否则,您将不得不适当地缩放工程图。