c# Take a WebPage Snapshot

Alright, it’s been a while, and this time around, I have something good! I have this situation where I want to take a screenshot programmatically from a web page. Although there are many examples out there for thumbnails, none really matched what I needed. I wanted to provide:

  • A maximum Width
  • A maximum Height
  • URL
  • Header (in case you need a special authentication header)

Turns out that everything was out there, scattered pieces here and bits there.

So I tinkered the whole thing together, and came up with something that works actually quite good! I still have one challenge left though: how can I put that in a DLL I can reuse and not get a threading issue? That is the question.

Here’s the code – pretty much self explanatory.

/// <summary>
/// Take a snapshot of a web page. Image will be truncated to the smallest of 
/// - smallest between rendered width and maximum width
/// - smallest between rendered height and maximum heigth
/// </summary>
/// <param name="webUrl">URL to take a snapshot from</param>
/// <param name="authHeader">Authentication header if needed</param>
/// <param name="maxWidth">Maximum width of the screenshot</param>
/// <param name="maxHeight">Maximum height of the screenshot</param>
/// <param name="output">output image file name</param>
[STAThread]
static void WebPageSnapshot(string webUrl, string authHeader, int maxWidth, int maxHeight, string output)
{
    Uri uri = new Uri(webUrl);

    WebBrowser browser = new WebBrowser();
    browser.Size = new System.Drawing.Size(maxWidth, maxHeight);
    browser.ScrollBarsEnabled = false;

    browser.Navigate(uri, "", null, authHeader);
    
    // This is what will make this render completely
    while (browser.ReadyState != WebBrowserReadyState.Complete)
    {
        Application.DoEvents();
    }
    using (Bitmap bitmap = new Bitmap(width, height))
    {
        Point location = webBrowser.Location;
        webBrowser.DrawToBitmap(bitmap, new Rectangle(location.X, location.Y, webBrowser.Width, webBrowser.Height));
        bitmap.Save(output, ImageFormat.Png);
    }
}

2 thoughts on “c# Take a WebPage Snapshot

  • March 29, 2019 at 15:22
    Permalink

    Hi Adeel,
    Sorry for the delay; I am rambling and sharing freely on this site, but I wasn’t really expecting questions since I don’t look at it that much (nor advertise this yet). But I will get there 🙂

    In the meantime – not sure what can cause this. I have tried it on my Windows 10 machine and on an Azure server; both worked well. I have updated the code though; the original code was a bit messy.
    You can give the updated code a try.

  • March 10, 2019 at 10:53
    Permalink

    Facing exception on this line:
    bitmap.Save(output, System.Drawing.Imaging.ImageFormat.Png);
    Exception:
    System.Runtime.InteropServices.ExternalException
    HResult=0x80004005
    Message=A generic error occurred in GDI+.
    Source=System.Drawing

Comments are closed.