将所有绘制的对象保存到位图中

Saving all Drawn Objects into a Bitmap

我有一个 Canvass (PictureBox),可以在上面绘制形状、图像或文本,如下图所示。我现在要做的是将它们全部保存到一个 BITMAP 文件 中。我不知道怎么开始?

PS:我正在使用不同的图形对象来绘制每个对象。

找到解决方法,这会将图纸保存在我的 pictureBox/Canvass 中。

private void button2_Click(object sender, EventArgs e)
    {
        SaveFileDialog save = new SaveFileDialog();

            //Creates a filter fir saving the Project File
            save.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp); *.PNG|*.jpg; *.jpeg; *.gif; *.bmp; *.PNG";     
            save.DefaultExt = ".bmp";
            save.AddExtension = true;

            if (save.ShowDialog() == DialogResult.OK)
            {
                using (var bmp = new Bitmap(pictureBox_Canvass.Width, pictureBox_Canvass.Height))
                {
                    pictureBox_Canvass.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
                    bmp.Save(save.FileName);
                }
            }
    }

样本输出

Graphics 是一个 "device context" 对象。它处理 Bitmap 上的绘图,但无法将其转换回 Bitmap

但是您可以复制已经绘制在 window 上的位,然后绘制到 Graphics。例如:

protected override void OnMouseClick(MouseEventArgs e)
{
    base.OnMouseClick(e);

    //get the screen coordinates for this window
    var rect = this.RectangleToScreen(this.ClientRectangle);

    //copy bits from screen to bitmap
    using (var bmp = new Bitmap(rect.Width, rect.Height))
    {
        var gr = Graphics.FromImage(bmp);
        gr.CopyFromScreen(rect.Left, rect.Top, 0, 0, rect.Size);

        //save to file
        bmp.Save(@"c:\test\test.bmp");
    }
}

或者您可以在响应 Windows 消息后立即执行此操作,但是您必须调用 Graphics::Flush 让 Windows 知道您何时完成绘画。此方法假定目标 window 可见。命令之间可能存在延迟,或者 window 的一部分不可见,并且您没有获得所需的输出。

另一个答案中提出了更好的解决方案:创建内存位图并在其上绘制。

如果你不想重复代码,你可以创建一个函数来处理window的设备上下文和内存设备上下文的所有绘画:

public void do_all_paintings(Graphics gr)
{
    //paint something random, add all other drawings
    gr.Clear(Color.Red);
}

现在响应 Windows 绘制请求进行绘制:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    do_all_paintings(e.Graphics);
}

使用相同的 do_all_paintings 函数创建文件以响应命令:

protected override void OnMouseClick(MouseEventArgs e)
{
    base.OnMouseClick(e);

    var rect = this.RectangleToScreen(this.ClientRectangle);
    using (var bmp = new Bitmap(rect.Width, rect.Height))
    {
        do_all_paintings(Graphics.FromImage(bmp));
        bmp.Save(@"c:\test\test.bmp");
    }
}