c# - 将面板保存到位图 c# Winforms

标签 c# winforms graphics panel gdi+

我有一个 Graphics 对象和一个 Panel。 Graphics 对象是用面板中的处理程序实例化的。然后,面板通过 Paint 操作进行更新。在 Paint 操作中,Graphics 对象用于绘画。有时,我在代码中使用 Invalidate() 来更新面板。

我想将Graphics对象的内容或Panel的内容保存到文件中。每当我尝试这样做时,都会创建图像文件,但它是空白的。

以下是一些代码片段:

我将 Graphics 对象初始化为类变量:

Graphics GD_LD;

然后在构造函数中,我使用以下代码通过面板处理程序实例化对象:

GD_LD = Graphics.FromHwnd(panelDrawLD.Handle);

然后,我有用于面板的 Paint 操作的绘图函数,如果我使用 Graphics 对象来制作所有绘图:

private void panelDrawLD_Paint(object sender, PaintEventArgs e)
{
    ..... some code ....
    //Code example
    GD_LD.FillPolygon(blackBrush, getPoints(min, sizeGP, scaleX, scaleY));
    GD_LD.FillPolygon(blackBrush, getPoints(max, sizeGP, scaleX, scaleY));
    ..... some code ....
}

上面的方法可以很好地在面板中绘图并使其始终与绘图保持一致。

问题是在尝试将面板保存到图像文件时:

Bitmap I_LD = new Bitmap(panelDrawLD.Size.Width, panelDrawLD.Size.Height);
panelDrawLD.DrawToBitmap(I_LD, new Rectangle(0,0, panelDrawLD.Size.Width, panelDrawLD.Size.Height));
I_LD.Save(tempPath + "I_LD.bmp",ImageFormat.Bmp);

图像文件已创建,但没有内容。只是空白。

我看到了一些关于这个主题的帖子,但我无法使其适应我的情况。

我做错了什么?可能的解决方案是什么?

最佳答案

您真正应该做的是将 Paint 事件重构为一个子例程,该子例程采用 Graphics 对象作为名为 target 的参数。根据目标进行所有绘图。然后,您可以调用它并从 panelDrawLD_Paint 传递 e.Graphics,并使用您使用 创建的 Graphics 从其他函数调用它Graphics.FromImage(I_LD).

此外,如果您创建Graphics(或任何其他 GDI 对象),您必须销毁它,否则会出现内存泄漏。

像这样:

private void panelDrawLD_Paint(object sender, PaintEventArgs e)
{
    //e.Graphics does NOT need to be disposed of because *we* did not create it, it was passed to us by the control its self.
    DrawStuff(e.Graphics);
}

private void Save()
{
    // I_LD, and g are both GDI objects that *we* created in code, and must be disposed of.  The "using" block will automatically call .Dispose() on the object when it goes out of scope.
    using (Bitmap I_LD = new Bitmap(panelDrawLD.Size.Width, panelDrawLD.Size.Height))
    {
        using (Graphics g = Graphics.FromImage(I_LD))
        {
            DrawStuff(g);
        }
        I_LD.Save(tempPath + "I_LD.bmp", ImageFormat.Bmp); 
    }   
}


private void DrawStuff(Graphics target)
{
    //Code example
    target.FillPolygon(blackBrush, getPoints(min, sizeGP, scaleX, scaleY));
    target.FillPolygon(blackBrush, getPoints(max, sizeGP, scaleX, scaleY));
}

关于c# - 将面板保存到位图 c# Winforms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47585042/

相关文章:

c# - 通过仅在基类中定义序列化方法来序列化具有继承性的对象?

c# - 为什么在文本更改组合框选择更改

c# - 如何在 C# Windows 窗体中隐藏关闭按钮

c# - IPreviewHandler 抛出无法捕获的异常

java - 如何用java把一张图片一分为二

c - C 和 Assembly 中 VGA 和 SVGA 编程的区别

c# - 针对匿名对象的 System.Text.Json 序列化

c# - 如何通过正则表达式设置第一个字符?

c# - 安装shield引用的项目dll

r - lattice auto.key - 如何调整线和点?