【问题标题】:Get what's drawn on panel to bitmap将面板上绘制的内容转换为位图
【发布时间】:2018-12-06 14:04:15
【问题描述】:

我的应用程序中有两个窗体。在主窗体上,我单击一个按钮并打开带有面板的第二个窗口。在面板上的那个表格中,我画了一些东西,我正在把它读到一个图片框上。

这是我的主要表单的编码。

        Bitmap retBmp;
        FrmDrawing frmDrawing = new FrmDrawing();
        var result = frmDrawing.ShowDialog();

        if (result == DialogResult.OK)
        {
            retBmp = frmDrawing.bmpNew;
            pbDesign.Image = retBmp;
        }

这就是我在第二个表格上的绘画方式。

public FrmDrawing()
        {
            InitializeComponent();
            g = pnlDraw.CreateGraphics();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            pen = new Pen(Color.Black, 5);
            pen.StartCap = pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
        }

        private void pbRed_Click(object sender, EventArgs e)
        {
            PictureBox p = (PictureBox)sender;
            pen.Color = p.BackColor;
        }

        private void pnlDraw_MouseDown(object sender, MouseEventArgs e)
        {
            moving = true;
            x = e.X;
            y = e.Y;
            pnlDraw.Cursor = Cursors.Cross;
        }

        private void pnlDraw_MouseMove(object sender, MouseEventArgs e)
        {
            if (moving && x!=-1 && y!=-1 )
            {
                g.DrawLine(pen, new Point(x, y), e.Location);
                x = e.X;
                y = e.Y;
            }
        }

        private void pnlDraw_MouseUp(object sender, MouseEventArgs e)
        {
            moving = false;
            x = -1;
            y = -1;
            pnlDraw.Cursor = Cursors.Default;

        }

        private void btnClear_Click(object sender, EventArgs e)
        {

            g.Clear(Color.White);
            pnlDraw.Invalidate();
        }

        private void btnAccept_Click(object sender, EventArgs e)
        {              

            bmpNew = new Bitmap(pnlDraw.Width, pnlDraw.Height);

            this.pnlDraw.DrawToBitmap(bmpNew, new Rectangle(0, 0, this.pnlDraw.Width, this.pnlDraw.Height));
            this.DialogResult = DialogResult.OK;
            this.Close();    
        }

在第二种形式中,我将面板上绘制的内容读取到 bmp,然后在单击按钮时将其传递给表单。这段代码几乎可以正常工作,除了它只通过面板而不是在上面绘制的内容。如果我在我绘制的面板上放置另外两个彩色图片框控件,则显示的图像带有这些彩色图片框,但不带有我在面板上绘制的内容。 阅读我在面板上绘制的位图时,我在这里做错了什么?或者为了让我在面板上绘制的位图应该更正什么。

【问题讨论】:

  • this post中的例子
  • g = pnlDraw.CreateGraphics(); 千万不要这样做!在 Paint 事件中绘制,然后使用 DrawToBitmap!
  • @RezaAghaei 我没有得到你在代码中所做的事情,你能给我一个与这个场景相关的例子吗?
  • @TaW 你能展示一个代码示例吗?
  • 手绘见here。对于使用 DrawToBirMap 进行保存,请参阅here。有关 CreateGraphics 的更多信息,请参阅here

标签: c# winforms bitmap panel draw


【解决方案1】:

首先,您可以阅读on MSDN

您通过CreateGraphics 方法检索到的Graphics 对象通常不应在处理当前Windows 消息后保留,因为使用该对象绘制的任何内容都将与下一条WM_PAINT 消息一起被删除。因此,您不能缓存 Graphics 对象以供重用,除非使用像 Graphics.MeasureString 这样的非可视方法。相反,您必须在每次要使用Graphics 对象时调用CreateGraphics,然后在使用完毕后调用Dispose

(强调我的)

因此您不应该在表单构造函数中创建Graphics 对象,您应该在事件处理程序中动态创建和处置它。

但这无论如何都帮不了你。尝试将表单移出屏幕并返回,您会注意到所有自定义绘图都消失了。这是因为您没有保留它们 - 它们只呈现一次。

不要使用面板,而是使用PictureBox 并直接在其Bitmap 上绘制线条。

pnlDraw 现在是 PictureBox,而不是 Panel

public FrmDrawing()
{
  InitializeComponent();
  pnlDraw.Image = new Bitmap(pnlDraw.Width, pnlDraw.Height);
}

private void pnlDraw_MouseMove(object sender, MouseEventArgs e)
{
    if (moving && x!=-1 && y!=-1 )
    {
        // Create Graphics object dynamically
        using (var g = Graphics.FromImage(pnlDraw.Image))
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            using (var pen = new Pen(Color.Black, 5))
            {
                pen.StartCap = pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;

                g.DrawLine(pen, new Point(x, y), e.Location);  
            }
        }

        // This is necessary; otherwise, we won't see the changes until
        // the picture box is repainted by the OS
        pnlDraw.Invalidate();

        x = e.X;
        y = e.Y;
    }
}

【讨论】:

  • 这没有帮助。我将控制器更改为图片框。并按照您的建议进行了代码修改。但这甚至没有像之前的代码那样在图片框上绘制任何东西。你能尝试提供一个更可行的解决方案吗?
  • 您需要调用Invalidate 方法来查看更改。此代码 100% 有效,因为我在发布之前在一个简单的 WinForms 应用程序中对其进行了测试。请注意,我没有包含您原来的 MouseDownMouseUp 事件处理程序。但是,它们仍然是必需的。
  • 嘿,它对我有用,但它借鉴了现有图像,我需要做什么来清除原始图像并围绕同一个中心旋转?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 2012-02-01
  • 2014-05-31
相关资源
最近更新 更多