DrawToBitmap 返回空白图像 [英] DrawToBitmap returning blank image

查看:34
本文介绍了DrawToBitmap 返回空白图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在从我的 winform 应用程序中创建位图图像时遇到问题.

I have a problem on creating bitmap image out of my winform application.

情况:

我有一个名为CanvasControl"的 UserControl,它接受 OnPaint 方法作为我的 Draw Pad 应用程序的画布.在此用户控件中,我有一个函数PrintCanvas()",它将创建 UserControl 的屏幕截图图像到 PNG 文件中.下面是 PrintCanvas() 函数:

I have a UserControl named as "CanvasControl" that accepts OnPaint method acting as canvas for my Draw Pad application. Inside this user control I have a function "PrintCanvas()" that will create a screenshot image of the UserControl into PNG file. Below is the PrintCanvas() function:

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 + 
        @"ExperimentFilesExperiment1" + filename, ImageFormat.Png);
    bmp.Dispose();
}

这个用户控件(CanvasControl)在我的主窗体中被调用,用户将在其中绘制一些东西,然后可以选择使用保存按钮进行保存.保存按钮会调出UserControlPrintCanvas()"函数.

This user control (CanvasControl) is called out inside my main form where user will draw something and have an option to save afterwards using a save button. The save button will call out the "PrintCanvas()" function of the UserControl.

我得到了预期的输出图像文件,但问题是它是一个空白图像.

I get the output image file as expected, but the problem is it was a blank image.

到目前为止我所尝试的:

What I have tried so far:

为了测试这不是语法问题,我尝试将 PrintCanvas() 函数转移到我的主窗体中,令人惊讶的是,我在文件中获得了整个主窗体的图像,但 UserControl 在那里不可见.

To test that it is not a syntax issue, I tried to transfer the PrintCanvas() function into my main form and surprisingly I get an image of the whole main form on file but the UserControl is not visible there.

我是否错过了任何其他设置以使 winform UserControl 可打印?

Is there any other setup i missed out to make a winform UserControl printable?

更新:(绘图程序)

  1. 充当画布的用户控件 - 此处代码

推荐答案

问题中的代码给出了第一个提示,但链接中的代码显示了问题的根源:您使用了 Graphics 绘图对象:

The code in the question gave a first hint but the code in the link showed the source of the problem: You use a 'wrong' instance of the Graphics object for drawing:

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 的参数 图形.

This is one of the most common mistakes with winforms graphics! Never use CreateGraphics ! You always should draw onto the control surface with the Graphics object in a Paint or DrawXXX event. These events have a parameter e.Graphics which is the only one that can draw persistent graphics.

持久意味着它总是会在必要时刷新,而不仅仅是在你触发它的时候.这是一个令人讨厌的错误,因为在您遇到外部事件需要重绘之前,一切似乎都正常工作:

Persistent means that it will always be refreshed when necessary, not just when you trigger it. This is a nasty error because everything seems to work until you come upon a situation when an outside event makes redrawing necessary:

  • 最小化然后最大化表单
  • 将其移出屏幕并再次移回
  • 调用DrawToBitmap
  • ...

请注意,只有当您使用 PaintEventArgs e 参数中的 有效和当前 Graphics 对象时,所有功能才会真正起作用.

Note that all will only really work if you use the valid and current Graphics object from the PaintEventArgs e parameter.

所以,解决方法很简单:

So, the solution is simple:

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 有什么用?只对引诱新手犯这种错误有好处??

But what is the CreateGraphics good for? It is only good for luring newbies into that error??

不完全;以下是它的一些用途:

Not quite; here are some uses for it:

  • 绘制非永久性图形,例如橡皮筋矩形或特殊鼠标光标
  • 在没有实际绘制的情况下使用 TextRendererMeasureString 方法测量文本大小
  • 使用Graphics.DpiX/Y
  • 查询屏幕或Bitmap分辨率
  • Drawing non-persistent graphics like a rubber-band rectangle or a special mouse cursor
  • Measuring text sizes without actually drawing it with a TextRenderer or the MeasureString method
  • Querying the screen or Bitmap resolution with Graphics.DpiX/Y

可能还有其他一些我现在想不起来的……

and probably some others I can't think of at the moment..

所以对于控件上的正常绘图总是使用 e.Grapahics 对象!您可以将其传递给子程序以使代码更有条理,但不要尝试缓存它;它必须是最新的!

So for normal drawing onto controls always use the e.Grapahics object! You can pass it on to subroutines to make the code more structured, but do not try to cache it; it needs to be current!

这篇关于DrawToBitmap 返回空白图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆