我有一个画布(PictureBox),可以在其上绘制形状,图像或文本,如下图所示。我现在要做的是将它们全部保存到一个 BITMAP文件中。我不知道如何开始?
PS:我正在使用不同的Graphics对象绘制每个对象。
答案 0 :(得分:2)
找到了一种解决方法,这会将图形保存在我的pictureBox /画布中。
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);
}
}
}
样品输出
答案 1 :(得分:1)
Graphics
是"device context"对象。它可以处理Bitmap
上的图形,但是不能将其转换回Bitmap
。
但是,您可以复制已经在窗口上绘制的位,然后绘制到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知道。此方法假定目标窗口是可见的。命令之间可能存在延迟,或者窗口的一部分不可见,并且您没有得到所需的输出。
另一个答案中提出了一个更好的解决方案:创建一个内存位图并在其上进行绘制。
如果不想重复代码,可以创建一个函数来处理窗口设备上下文和内存设备上下文的所有绘制:
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");
}
}