从WebBrower组件中获取全页截图

4
我尝试使用WebBrowser组件捕获用户正在浏览的任何网站的全屏截图。目前,我只能捕获用户从WebBrowser中查看的内容。但是,创建的截图图像是网页的大小。例如,下面是BBC网站的(半尺寸)屏幕截图,黑色区域实际上保存为透明,但为了方便查看,我已将其填充为黑色。
我已经看到一些解决方案,其中使用新的WebBrowser实例来获取全屏快照。但是,我需要截图与用户在此时此刻查看的页面完全相同,就像Firefox中的全屏截图一样工作。
以下是生成上述图像的代码:
private void button1_Click(object sender, EventArgs e)
{

        while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        int scrollWidth = 0;
        int scrollHeight = 0;

        scrollHeight = webBrowser1.Document.Body.ScrollRectangle.Height;
        scrollWidth = webBrowser1.Document.Body.ScrollRectangle.Width;
        webBrowser1.Size = new Size(scrollWidth, scrollHeight);
        Bitmap bm = new Bitmap(scrollWidth, scrollHeight);

        webBrowser1.DrawToBitmap(bm, new Rectangle(0, 0, bm.Width, bm.Height));
        bm.Save(@"D:\Screenshots\test.png", ImageFormat.Png);


  }

我认为问题出在DrawToBitmap返回的PNG上。你能检查一下生成的图像中有多少百分比是黑色的吗?是三分之二还是类似的比例?另一种可能是图像大小。由于我猜测DrawToBitmap函数会填充空白和黑色空间而不是降低文件分辨率,所以它可能不适合你。尝试寻找其他替代方案(也许是与JPEG一起使用的东西?) - A. Abramov
@A.Abramov: 我猜问题在于DrawToBitmap可能会以当前Web浏览器控件的大小来呈现,但他想呈现整个页面。 - Dark Falcon
@Dark Falcon 我不这么认为,因为那样会在网页浏览器之前裁剪图片,而我们现在讨论的是在网站本身中太多后期处理图像。 - A. Abramov
@A.Abramov:如果您查看图像底部,显然有更多未呈现的网页。底部有一个标题,图片看起来太短了。从代码上看,我发现他试图将控件调整为页面的滚动大小。我的猜测是,虽然控件现在足够大,但它尚未完成重新计算页面布局。 - Dark Falcon
我相信这个问题出在 DrawToBitmap 上,因为有时它会生成一个纯白的页面。虽然我不能确定。 - TEK
1个回答

2
我有一个可靠的工作中。。
 private void button1_Click(object sender, EventArgs e)
    {
       using (FileDialog fd = new SaveFileDialog())
        {
            fd.Filter = "Image (*.png)|*.png";
            if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                new WebPageSnap(webBrowser1.Url.ToString(), fd.FileName);
                //might take 3 or 4 seconds to save cauz it has to load again.
            }
        }
    }

    class WebPageSnap
    {
        WebBrowser wb;
        string outFile;

        public WebPageSnap(string url, string outputFile)
        {
            wb = new WebBrowser();
            wb.ProgressChanged += wb_ProgressChanged;
            outFile = outputFile;
            wb.ScriptErrorsSuppressed = true;
            wb.ScrollBarsEnabled = false;
            wb.Navigate(url);
        }

        void wb_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
        {
            if (e.CurrentProgress == e.MaximumProgress)
            {
                wb.ProgressChanged -= wb_ProgressChanged;
                try
                {
                    int scrollWidth = 0;
                    int scrollHeight = 0;

                    scrollHeight = wb.Document.Body.ScrollRectangle.Height;
                    scrollWidth = wb.Document.Body.ScrollRectangle.Width;
                    wb.Size = new Size(scrollWidth, scrollHeight);


                    Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
                    for (int Xcount = 0; Xcount < bitmap.Width; Xcount++)
                        for (int Ycount = 0; Ycount < bitmap.Height; Ycount++)
                            bitmap.SetPixel(Xcount, Ycount, Color.Black);
                    wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
                    bitmap.Save(outFile, ImageFormat.Png);
                }
                catch { }
            }
        }

    }

.

;Here's the result

.

enter image description here


我在实验中发现的主要问题是,当前可见和正在使用的WebBrowser控件无法绘制到位图。需要实例化一个新的控件,但不要将其添加到任何窗体中,然后将URL应用于它,加载并捕获图像。 - Abdul Saleem
这是一个很好而且聪明的回答。不幸的是,由于项目的性质,截图必须是当前页面正在查看的状态。 - TEK
为什么你不能这样做呢?当用户点击按钮时,打开一个文件保存对话框,当 DialogResult.OK 时,使用如下方式——> new WebPageSnap(webBrowser1.Url.ToString(), fileDialog1.FileName); - Abdul Saleem
您当前的浏览器控件不会被中断,图片可以保存。您需要解释吗? - Abdul Saleem
页面加载后,是否可以在按钮单击时执行?我非常感谢您的努力,谢谢。 - TEK
这个解决方案需要一个新的浏览器实例。截图必须是当前网站的实时视图,遗憾的是,如果重新加载网站,其内容可能会发生变化,对于这个应用程序来说是不好的。再次感谢您。 - TEK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接