Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在线程中执行Webbrowser控件的屏幕scape_C#_Multithreading_Webbrowser Control_Screen Scraping_Apartments - Fatal编程技术网

C# 在线程中执行Webbrowser控件的屏幕scape

C# 在线程中执行Webbrowser控件的屏幕scape,c#,multithreading,webbrowser-control,screen-scraping,apartments,C#,Multithreading,Webbrowser Control,Screen Scraping,Apartments,我正在使用中显示的技术 当WebBrowser控件放置在WinForm上时,我尝试获取网页的屏幕截图,成功地获得了以下代码。但是,当在线程中运行时,它会提供桌面的任意图像,从而失败 Thread browserThread = new Thread(() => { WebBrowser br = new WebBrowser(); br.DocumentCompleted += webBrowser1_DocumentCompleted; br.ProgressC

我正在使用中显示的技术

WebBrowser
控件放置在
WinForm
上时,我尝试获取网页的屏幕截图,成功地获得了以下代码。但是,当在线程中运行时,它会提供桌面的任意图像,从而失败

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()方法的缘故,但我不知道还有其他方法。有没有任何人可以建议的解决这个问题的方法?或者,我唯一的选择是创建表单、添加控件、使其可见,然后进行屏幕清理?出于显而易见的原因,我希望避免这种做法

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);
    }
你真的需要吗

您也
返回图像
,但复制的图像是如何分配给它的

你可以写

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;
}
完整的工作代码

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

公共类WebUtils
{
公共静态任务GetPageAsImageAsync(字符串url)
{
var tcs=new TaskCompletionSource();
变量线程=新线程(()=>
{
WebBrowser browser=新的WebBrowser();
browser.Size=新尺寸(1280768);
WebBrowserDocumentCompletedEventHandler documentCompleted=null;
documentCompleted=异步(o,s)=>
{
browser.DocumentCompleted-=DocumentCompleted;
等待任务。延迟(2000);//再运行JS几秒钟
位图位图=快照(浏览器);
tcs.TrySetResult(位图);
browser.Dispose();
Application.ExitThread();
};
browser.ScriptErrorsSuppressed=true;
browser.DocumentCompleted+=DocumentCompleted;
浏览器.导航(url);
Application.Run();
});
SetApartmentState(ApartmentState.STA);
thread.Start();
返回tcs.Task;
}
私有静态位图快照(WebBrowser浏览器)
{
browser.Width=browser.Document.Body.ScrollRectangle.Width;
browser.Height=browser.Document.Body.ScrollRectangle.Height;
位图位图=新位图(browser.Width-System.Windows.Forms.SystemInformation.VerticalScrollBarWidth,browser.Height);
DrawToBitmap(位图,新矩形(0,0,bitmap.Width,bitmap.Height));
返回位图;
}
}

正是我所需要的。我寻找了类似WebBrowser.DrawToBitmap()的东西,但它没有出现在intellisense中(现在仍然没有),但编译很好。非常感谢。同时感谢您显示System.Windows.Forms.SystemInformation。以前从未见过,显然非常有用。太好了。正是我所需要的。不使用语句编写示例代码。唉。@RobertHarvey感谢VS,它很容易解决:)是的,你需要使用,除非你有很好的理由不处理你应该处理的IDisposable对象。对于图像,它是通过线条Graphics=Graphics.FromImage(图像)指定的。
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;
    }
}