执行线程WebBrowser控件屏幕景观

执行线程WebBrowser控件屏幕景观

本文介绍了执行线程WebBrowser控件屏幕景观的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用中所示的技术

WebBrowser控制在一个新的线程

试图获得一个网页,我已经能够得到以下code能够成功运行,当 web浏览器控件放置在了屏幕刮的WinForm 。但是它不能由一个线程中运行时,提供桌面的任意图像。

Trying to get a screen-scrape of a webpage I have been able to get the following code to successfully work when the WebBrowser control is placed on a WinForm. However it fails by providing an arbitrary image of the desktop when run inside a thread.

Thread browserThread = new Thread(() =>
{
    WebBrowser br = new WebBrowser();
    br.DocumentCompleted += webBrowser1_DocumentCompleted;
    br.ProgressChanged += webBrowser1_ProgressChanged;
    br.ScriptErrorsSuppressed = true;
    br.Navigate(url);
    Application.Run();
});
browserThread.SetApartmentState(ApartmentState.STA);
browserThread.Start();

private Image TakeSnapShot(WebBrowser browser)
{
    int width;
    int height;

    width = browser.ClientRectangle.Width;
    height = browser.ClientRectangle.Height;

    Bitmap image = new Bitmap(width, height);

    using (Graphics graphics = Graphics.FromImage(image))
    {
        Point p = new Point(0, 0);
        Point upperLeftSource = browser.PointToScreen(p);
        Point upperLeftDestination = new Point(0, 0);

        Size blockRegionSize = browser.ClientRectangle.Size;
        blockRegionSize.Width = blockRegionSize.Width - 15;
        blockRegionSize.Height = blockRegionSize.Height - 15;
        graphics.CopyFromScreen(upperLeftSource, upperLeftDestination, blockRegionSize);
    }

    return image;
}

这显然是因为该方法 Graphics.CopyFromScreen(),但我不知道任何其他的办法。有没有办法解决这个问题,任何人都可以提出一个方法?或者是我创建一个表单,添加控件,使其可见,然后屏幕刮唯一的选择?由于显而易见的原因,我希望避免这样的做法。

This obviously happens because of the method Graphics.CopyFromScreen() but I am unaware of any other approach. Is there a way to resolve this issue that anyone could suggest? or is my only option to create a form, add the control, make it visible and then screen-scrape? For obvious reasons I'm hoping to avoid such an approach.

推荐答案

您可以写

private Image TakeSnapShot(WebBrowser browser)
{
     browser.Width = browser.Document.Body.ScrollRectangle.Width;
     browser.Height= browser.Document.Body.ScrollRectangle.Height;

     Bitmap bitmap = new Bitmap(browser.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, browser.Height);

     browser.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));

     return bitmap;
}

一个完整的工作code

A full working code

var image = await WebUtils.GetPageAsImageAsync("http://www.stackoverflow.com");
image.Save(fname , System.Drawing.Imaging.ImageFormat.Bmp);


public class WebUtils
{
    public static Task<Image> GetPageAsImageAsync(string url)
    {
        var tcs = new TaskCompletionSource<Image>();

        var thread = new Thread(() =>
        {
            WebBrowser browser = new WebBrowser();
            browser.Size = new Size(1280, 768);

            WebBrowserDocumentCompletedEventHandler documentCompleted = null;
            documentCompleted = async (o, s) =>
            {
                browser.DocumentCompleted -= documentCompleted;
                await Task.Delay(2000); //Run JS a few seconds more

                Bitmap bitmap = TakeSnapshot(browser);

                tcs.TrySetResult(bitmap);
                browser.Dispose();
                Application.ExitThread();
            };

            browser.ScriptErrorsSuppressed = true;
            browser.DocumentCompleted += documentCompleted;
            browser.Navigate(url);
            Application.Run();
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();

        return tcs.Task;
    }

    private static Bitmap TakeSnapshot(WebBrowser browser)
    {
         browser.Width = browser.Document.Body.ScrollRectangle.Width;
         browser.Height= browser.Document.Body.ScrollRectangle.Height;

         Bitmap bitmap = new Bitmap(browser.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, browser.Height);

         browser.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));

         return bitmap;
    }
}

这篇关于执行线程WebBrowser控件屏幕景观的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 06:27