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