Taking Thumbnails of a Website


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