
I always wondered how web directories take thumbnail snapshots of my blog when I register with them. And yesterday I had some free time to find out how it could be done in C#. I used the WebBrowser control to achieve this. Here is how I did it.
I created four fields, one WebBrowser control and three Bitmap objects for the three different sizes of thumbnails I want to display and save. The three Bitmap objects are not necessary, I could have used one object to display the three different sizes, but it helped me reduce the code of the save buttons. In the Constructor I initialized the WebBrowser control’s size to 800 by 600, which is the smallest size for most websites to be viewable without messing up the design. I also removed the scrollbars and initialized the delegate for the DocumentCompleted event.
private WebBrowser wb = new WebBrowser();
private Bitmap screenshot300x225;
private Bitmap screenshot200x150;
private Bitmap screenshot100x75;
public MainForm()
{
InitializeComponent();
wb.Height = 600;
wb.Width = 800;
wb.ScrollBarsEnabled = false;
wb.DocumentCompleted += new
WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
}
The WebBrowser’s DocumentCompleted event is where the screenshots are taken and apparently this is the only place the DrawToBitmap method can be called. The DrawToBitmap is a method inherited from the WebBrowserBase object and MSDN says “This API supports the .NET Framework infrastructure and is not intended to be used directly from your code”, so it is not visible in IntelliSense. It takes two parameters, the first is the Bitmap object to store the screenshot in and the second the Rectangle object defining the bounds of the screenshot. After that the three Bitmap fields are initialized and displayed on the PictureBox controls.
void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
Bitmap bmp = new Bitmap(800, 600);
wb.DrawToBitmap(bmp,
new Rectangle(wb.Location.X, wb.Location.Y, wb.Width, wb.Height));
screenshot100x75 = new Bitmap(bmp, 100, 75);
screenshot200x150 = new Bitmap(bmp, 200, 150);
screenshot300x225 = new Bitmap(bmp, 300, 250);
smallPictureBox.Image = screenshot100x75;
mediumPictureBox.Image = screenshot200x150;
largePictureBox.Image = screenshot300x225;
this.Cursor = Cursors.Default;
}
private void captureButton_Click(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
wb.Navigate(urlTextBox.Text);
}
private void saveSmallButton_Click(object sender, EventArgs e)
{
if (screenshot100x75 != null)
{
if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
screenshot100x75.Save(saveFileDialog1.FileName);
}
}
private void saveMediumButton_Click(object sender, EventArgs e)
{
if (screenshot200x150 != null)
{
if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
screenshot200x150.Save(saveFileDialog1.FileName);
}
}
private void saveLargeButton_Click(object sender, EventArgs e)
{
if (screenshot300x225 != null)
{
if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
screenshot300x225.Save(saveFileDialog1.FileName);
}
}
Download Source Code
Related posts:





Interesting code. Nice work. Could use something like that!
[...] few weeks ago I posted Taking Thumbnails of a Website, that shows how to take a screen shot of a website using the Web Browser control. I used the code [...]
Thank you blogville, appreciate it
Unfortunately, there’s one small problem with this. Don’t use Google as your demonstration project.. use Digg, or Slashdot. What you’ll notice.. is the cropping! The method that you’re using will only grab 800×600, not 800×4000.
Personally, I think that’s a bit annoying.. but you’re definitely spot on for what you need to do, to do what you’re doing. There isn’t a better solution that I’ve found yet for grabbing an entire thumbnail of a webpage.
It would be nice if we could do this without relying on the WebBrowser control as well. I looked once at WebKit.. there was a .NET port, but it wasn’t finished/working, etc.
- Matthew
Thank you Matthew for the comment. Could you please download the source code of SiteCapture, an small app I developed based on the code in this post, maybe it does what you are looking for. The link is at the top of the page.
Taking Thumbnails of a Website | CodeHill…
Thank you for submitting this cool story – Trackback from DotNetShoutout…
Hi I am facing an issue once publishing the image grabbing functionality on shared hosting I am getting an network related issue.
I talk to service providers also, and they are not able to help me out, can anyone let me know how we can come from the issue.
Please find the URL of my test page.
http://thefogochannel.com/TestHandler.aspx
My sample code is as follows:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Threading;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
public partial class TestHandler : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnShowThumbnailImage_Click(object sender, EventArgs e)
{
string address = “http://” + txtWebsiteAddress.Text;
int width = Int32.Parse(txtWidth.Text);
int height = Int32.Parse(txtHeight.Text);
Bitmap bmp = GetWebSiteThumbnail(address, 800, 600, width, height);
bmp.Save(Server.MapPath(“~”) + “/images/uploads/thumbnail.bmp”);
imgWebsiteThumbnailImage.ImageUrl = “~/images/uploads/thumbnail.bmp”;
imgWebsiteThumbnailImage.Visible = true;
}
public static Bitmap GetWebSiteThumbnail(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
{
WebsiteThumbnailImage thumbnailGenerator = new WebsiteThumbnailImage(Url, BrowserWidth, BrowserHeight, ThumbnailWidth, ThumbnailHeight);
return thumbnailGenerator.GenerateWebSiteThumbnailImage();
}
private class WebsiteThumbnailImage
{
public WebsiteThumbnailImage(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
{
this.m_Url = Url;
this.m_BrowserWidth = BrowserWidth;
this.m_BrowserHeight = BrowserHeight;
this.m_ThumbnailHeight = ThumbnailHeight;
this.m_ThumbnailWidth = ThumbnailWidth;
}
private string m_Url = null;
public string Url
{
get
{
return m_Url;
}
set
{
m_Url = value;
}
}
private Bitmap m_Bitmap = null;
public Bitmap ThumbnailImage
{
get
{
return m_Bitmap;
}
}
private int m_ThumbnailWidth;
public int ThumbnailWidth
{
get
{
return m_ThumbnailWidth;
}
set
{
m_ThumbnailWidth = value;
}
}
private int m_ThumbnailHeight;
public int ThumbnailHeight
{
get
{
return m_ThumbnailHeight;
}
set
{
m_ThumbnailHeight = value;
}
}
private int m_BrowserWidth;
public int BrowserWidth
{
get
{
return m_BrowserWidth;
}
set
{
m_BrowserWidth = value;
}
}
private int m_BrowserHeight;
public int BrowserHeight
{
get
{
return m_BrowserHeight;
}
set
{
m_BrowserHeight = value;
}
}
public Bitmap GenerateWebSiteThumbnailImage()
{
Thread m_thread = new Thread(new ThreadStart(_GenerateWebSiteThumbnailImage));
m_thread.SetApartmentState(ApartmentState.STA);
m_thread.Start();
m_thread.Join();
return m_Bitmap;
}
private void _GenerateWebSiteThumbnailImage()
{
WebBrowser m_WebBrowser = new WebBrowser();
m_WebBrowser.ScrollBarsEnabled = false;
m_WebBrowser.Navigate(m_Url);
m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
m_WebBrowser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser m_WebBrowser = (WebBrowser)sender;
m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
m_WebBrowser.ScrollBarsEnabled = false;
m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
m_WebBrowser.BringToFront();
m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
}
}
}