DrawToBitmap 返回空白图像
DrawToBitmap returning blank image
我在使用 winform 应用程序创建位图图像时遇到问题。
情况:
我有一个名为“CanvasControl
”的 UserControl
,它接受 OnPaint
方法作为我的 Draw Pad 应用程序的 canvas。在这个用户控件中,我有一个函数“PrintCanvas()
”,它会将 UserControl
的屏幕截图图像创建到 PNG 文件中。下面是 PrintCanvas()
函数:
public void PrintCanvas(string filename = "sample.png")
{
Graphics g = this.CreateGraphics();
//new bitmap object to save the image
Bitmap bmp = new Bitmap(this.Width, this.Height);
//Drawing control to the bitmap
this.DrawToBitmap(bmp, new Rectangle(0, 0, this.Width, this.Height));
bmp.Save(Application.StartupPath +
@"\ExperimentFiles\Experiment1" + filename, ImageFormat.Png);
bmp.Dispose();
}
此用户控件 (CanvasControl
) 在我的主窗体中调用,用户将在其中绘制一些内容,然后可以选择使用保存按钮进行保存。保存按钮会调出UserControl
.
的“PrintCanvas()
”函数
我得到了预期的输出图像文件,但问题是它是一张空白图像。
到目前为止我尝试过的:
为了测试这不是语法问题,我尝试将 PrintCanvas()
函数转移到我的主窗体中,令人惊讶的是我在文件中得到了整个主窗体的图像,但是 UserControl
在那里不可见。
我是否错过了任何其他设置来使 winform UserControl
可打印?
更新:(绘图例程)
- 用户控件充当 canvas - code here
问题中的代码给出了第一个提示,但 link 中的代码显示了问题的根源:您使用 Graphics
对象的 'wrong' 实例进行绘图:
protected override void OnPaint(PaintEventArgs e)
{
// If there is an image and it has a location,
// paint it when the Form is repainted.
Graphics graphics = this.CreateGraphics();
..
这是winforms图形最常见的错误之一! 切勿使用 CreateGraphics!您始终应该在 Paint 或 DrawXXX 事件中使用 Graphics 对象在控制面上绘图。 这些事件有一个参数 e.Graphics
,它是唯一可以绘制 persistent 图形。
Persistent的意思是它会一直在需要的时候刷新,而不仅仅是你触发它的时候。这是一个严重的错误,因为在您遇到外部事件需要重新绘制的情况之前,一切似乎都正常:
- 最小化然后最大化表单
- 将其移出屏幕再移回
- 呼叫
DrawToBitmap
- ...
请注意,只有当您使用 PaintEventArgs e
参数中的 有效和当前 Graphics
对象时,所有这些才会真正起作用。
所以,解决方法很简单:
protected override void OnPaint(PaintEventArgs e)
{
// If there is an image and it has a location,
// paint it when the Form is repainted.
Graphics graphics = e.Graphics(); // << === !!
..
但是 CreateGraphics
有什么用?只是为了引诱新手犯那个错误??
不完全是;这里有一些用途:
- 绘制非持久图形,如橡皮筋矩形或特殊鼠标光标
- 使用
TextRenderer
或 MeasureString
方法测量文本大小而不实际绘制它
- 查询屏幕或
Bitmap
分辨率 Graphics.DpiX/Y
可能还有一些我现在想不起来的..
所以要在控件上正常绘制 总是 使用 e.Grapahics
对象!您可以将它传递给子例程以使代码更加结构化,但不要尝试缓存它;它必须是最新的!
我在使用 winform 应用程序创建位图图像时遇到问题。
情况:
我有一个名为“CanvasControl
”的 UserControl
,它接受 OnPaint
方法作为我的 Draw Pad 应用程序的 canvas。在这个用户控件中,我有一个函数“PrintCanvas()
”,它会将 UserControl
的屏幕截图图像创建到 PNG 文件中。下面是 PrintCanvas()
函数:
public void PrintCanvas(string filename = "sample.png")
{
Graphics g = this.CreateGraphics();
//new bitmap object to save the image
Bitmap bmp = new Bitmap(this.Width, this.Height);
//Drawing control to the bitmap
this.DrawToBitmap(bmp, new Rectangle(0, 0, this.Width, this.Height));
bmp.Save(Application.StartupPath +
@"\ExperimentFiles\Experiment1" + filename, ImageFormat.Png);
bmp.Dispose();
}
此用户控件 (CanvasControl
) 在我的主窗体中调用,用户将在其中绘制一些内容,然后可以选择使用保存按钮进行保存。保存按钮会调出UserControl
.
PrintCanvas()
”函数
我得到了预期的输出图像文件,但问题是它是一张空白图像。
到目前为止我尝试过的:
为了测试这不是语法问题,我尝试将 PrintCanvas()
函数转移到我的主窗体中,令人惊讶的是我在文件中得到了整个主窗体的图像,但是 UserControl
在那里不可见。
我是否错过了任何其他设置来使 winform UserControl
可打印?
更新:(绘图例程)
- 用户控件充当 canvas - code here
问题中的代码给出了第一个提示,但 link 中的代码显示了问题的根源:您使用 Graphics
对象的 'wrong' 实例进行绘图:
protected override void OnPaint(PaintEventArgs e)
{
// If there is an image and it has a location,
// paint it when the Form is repainted.
Graphics graphics = this.CreateGraphics();
..
这是winforms图形最常见的错误之一! 切勿使用 CreateGraphics!您始终应该在 Paint 或 DrawXXX 事件中使用 Graphics 对象在控制面上绘图。 这些事件有一个参数 e.Graphics
,它是唯一可以绘制 persistent 图形。
Persistent的意思是它会一直在需要的时候刷新,而不仅仅是你触发它的时候。这是一个严重的错误,因为在您遇到外部事件需要重新绘制的情况之前,一切似乎都正常:
- 最小化然后最大化表单
- 将其移出屏幕再移回
- 呼叫
DrawToBitmap
- ...
请注意,只有当您使用 PaintEventArgs e
参数中的 有效和当前 Graphics
对象时,所有这些才会真正起作用。
所以,解决方法很简单:
protected override void OnPaint(PaintEventArgs e)
{
// If there is an image and it has a location,
// paint it when the Form is repainted.
Graphics graphics = e.Graphics(); // << === !!
..
但是 CreateGraphics
有什么用?只是为了引诱新手犯那个错误??
不完全是;这里有一些用途:
- 绘制非持久图形,如橡皮筋矩形或特殊鼠标光标
- 使用
TextRenderer
或MeasureString
方法测量文本大小而不实际绘制它 - 查询屏幕或
Bitmap
分辨率Graphics.DpiX/Y
可能还有一些我现在想不起来的..
所以要在控件上正常绘制 总是 使用 e.Grapahics
对象!您可以将它传递给子例程以使代码更加结构化,但不要尝试缓存它;它必须是最新的!