如何克服winform的Control.DrawToBitmap()方法大尺寸限制 [英] How to overcome the winform's Control.DrawToBitmap() method large size limitation

查看:40
本文介绍了如何克服winform的Control.DrawToBitmap()方法大尺寸限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 C#、Winforms 和 MS Visual Studio 2010 开发桌面应用程序.在应用程序中,我必须截取窗体面板的屏幕截图并将图像保存在光盘中.面板尺寸可以很大.我使用 Panel.DrawToBitmap() 方法来保存面板的图像.但是,当面板尺寸太大时,它会抛出异常.我在 msdn ( http://msdn.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap%28v=vs.110%29.aspx) 用于大尺寸控件,Control.DrawToBitmap 方法将不起作用.有没有其他方法,我可以实现类似的行为来克服大小限制.请注意,面板尺寸可能会有所不同.

更新:我找到了 Control.DrawToBitmap 的替代方法:WebBrowser.DrawToBitmap() 或其他方法?.但是,它只捕获控件的可见部分.

解决方案

这个问题让我对很多事情感到困惑..

这是一个从相当大的Panel 写入图像文件的解决方案..

限制因素之一是生成的位图的大小.我已经测试了最大 12.5k * 25k 的大小并发现它可以正常工作;不过,尺寸可能取决于您的机器.我认为您需要相当多的连续内存来创建如此大的Bitmap.

另一个问题是,正如您的标题所暗示的,确实与 DrawToBitmap 方法本身有关.它看起来好像不能可靠地写入大型位图,这就是为什么我必须将其结果缓冲在临时位图中.如果控件的任何维度超过某个大小,可能是 4k,但也可能不会.

该解决方案首先创建Panel 大小的Bitmap.然后它创建一个临时的 Panel 来容纳大的 Panel.这个容器足够小,DrawToBitmap 可以工作.

然后它在宽度和高度上循环,向上和向左移动大Panel,粘贴DrawToBitmap带回来的部分,一步一步进入大位图.

最后将其写回 PNG 以获得最佳可读性和大小..

private void button2_Click(object sender, EventArgs e){Bitmap bmp = new Bitmap(largePanel.ClientSize.Width, largePanel.ClientSize.Height);DrawToBitmap(largePanel, bmp);//拼凑方法bmp.Save(yourFileName, System.Drawing.Imaging.ImageFormat.Png);bmp.Dispose();//摆脱大的!GC.Collect();//不知道为什么,但它有帮助}void DrawToBitmap(Control ctl, Bitmap bmp){光标 = Cursors.WaitCursor;//是的,需要一段时间面板 p = 新面板();//包含面板点 oldLocation = ctl.Location;//p.Location = Point.Empty;//this.Controls.Add(p);//int maxWidth = 2000;//您可能想尝试其他尺寸int maxHeight = 2000;//Bitmap bmp2 = new Bitmap(maxWidth, maxHeight);//缓冲区p.Height = maxHeight;//设置..p.Width = maxWidth;//..容器ctl.Location = new Point(0, 0);//初始点ctl.Parent = p;//容器内部p.Show();//p.BringToFront();////我们将使用 G 在大位图上绘制使用 (Graphics G = Graphics.FromImage(bmp))for (int y = 0; y 

我在 Panel 上绘制了一些东西,并投入了几百个 Buttons,结果看起来是无缝的.无法发布,原因很明显..

*** 注意:如果您的面板不在表单上,​​您应该将 this 更改为真正的 Parent

I am developing an desktop application using C#, Winforms, and MS Visual Studio 2010. In the application, I have to take the screenshot of a panel of a form and save the image in disc. The panel size can be large. I have used Panel.DrawToBitmap() method to save the image of the panel. But, when the panel size is too large, it throws exception. I have found in msdn ( http://msdn.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap%28v=vs.110%29.aspx) that for large size control, the method Control.DrawToBitmap will not work. Is there any alternative way, I can achieve the similar behavior overcoming the size limitation. It is to be noted the panel size can vary.

Update: I have found alternative of Control.DrawToBitmap : WebBrowser.DrawToBitmap() or other methods?. But, it only captures the visible part of the control.

解决方案

This question had me confused about quite a few things..

Here is a solution that writes an image file from a Panel of rather large sizes..

One of the limiting factors is the size of the resulting Bitmap. I have tested for sizes of up to 12.5k * 25k and found it to work fine; the sizes may depend on your machine, though. I think you need quite some contiguous memory to create such a large Bitmap.

The other problem is, as your title suggests, indeed with the DrawToBitmap method itself. It looks as if it can't reliably write onto large Bitmaps, which is why I had to buffer its results in a temporary Bitmap. Nor can it work if any dimension of the control is over some size, maybe 4k, but maybe not..

The solution first creates a Bitmap of the Panel's size. Then it creates a temporary Panel to house the large Panel. This container it small enough for DrawToBitmap to work.

Then it loops over the width and height, moving the large Panel up and left, pasting the portions DrawToBitmap brings back, step by step into the large Bitmap.

Finally it writes it back as PNG for best readability and size..

private void button2_Click(object sender, EventArgs e)
{
    Bitmap bmp = new Bitmap(largePanel.ClientSize.Width, largePanel.ClientSize.Height);

    DrawToBitmap(largePanel, bmp);      // the patchwork method

    bmp.Save(yourFileName, System.Drawing.Imaging.ImageFormat.Png);
    bmp.Dispose();                      // get rid of the big one!

    GC.Collect();                       // not sure why, but it helped
}


void DrawToBitmap(Control ctl, Bitmap bmp)
{
    Cursor = Cursors.WaitCursor;         // yes it takes a while
    Panel p = new Panel();               // the containing panel
    Point oldLocation = ctl.Location;    // 
    p.Location = Point.Empty;            //
    this.Controls.Add(p);                //

    int maxWidth = 2000;                 // you may want to try other sizes
    int maxHeight = 2000;                //

    Bitmap bmp2 = new Bitmap(maxWidth, maxHeight);  // the buffer

    p.Height = maxHeight;               // set up the..
    p.Width = maxWidth;                 // ..container

    ctl.Location = new Point(0, 0);     // starting point
    ctl.Parent = p;                     // inside the container
    p.Show();                           // 
    p.BringToFront();                   //

    // we'll draw onto the large bitmap with G
    using (Graphics G = Graphics.FromImage(bmp))
    for (int y = 0; y < ctl.Height; y += maxHeight)
    {
        ctl.Top = -y;                   // move up
        for (int x = 0; x < ctl.Width; x += maxWidth)
        {
            ctl.Left = -x;             // move left
            p.DrawToBitmap(bmp2, new Rectangle(0, 0, maxWidth, maxHeight));
            G.DrawImage(bmp2, x, y);   // patch together
        }
    }

    ctl.Location = p.Location;         // restore..
    ctl.Parent = this;                 // form layout <<<==== ***
    p.Dispose();                       // clean up

    Cursor = Cursors.Default;          // done
}

I have drawn a few things onto the Panel and thrown in a few hundred Buttons and the result looks seamless. Can't post it, for obvious reasons..

*** Note: If your Panel doesn't sit on the form you should change this to the real Parent!

这篇关于如何克服winform的Control.DrawToBitmap()方法大尺寸限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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