将所有绘制的对象保存到位图中
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");
}
}
我有一个 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");
}
}