Perform screen-scape of Webbrowser control in thread

前端 未结 2 1366
抹茶落季
抹茶落季 2020-11-29 10:16

I am using the technique shown in

WebBrowser Control in a new thread

Trying to get a screen-scrape of a webpage I have been abl

相关标签:
2条回答
  • 2020-11-29 10:17

    You can write

    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;
    }
    

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-29 10:19
    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);
        }
    

    Do you really need using statement ?

    You also return image but how is copied image assigned to it?

    0 讨论(0)
提交回复
热议问题