Sample application screenshot
Introduction
This sample code/website gets the thumbnail/screenshot for a specific URL, giving the browser dimensions and the thumbnail dimensions you want.
Background
Well, tired of search for a method for giving me the screenshot of a URL, and just finding examples of Windows.Forms, with the simple method DrawToBitmap
, I just realized that in ASP.NET, that does not work like that, because of Single Thread and Multi Thread; so I used .SetApartmentState(ApartmentState.STA)
to make it single threaded.
Using the Code
Just call the method that you want to associate with the ImageUrl
of an ASP.NET Image
control.
Server-side
Calling with the IHttpHandler Method
ImageBox.ImageUrl = "~/HandlerWSThumb.ashx?url=" +
Server.UrlEncode(txtURL.Text).ToLower().ToString() + "&bw=" +
txtBW.Text + "&bh=" + txtBH.Text + "&tw=" +
txtTW.Text + "&th=" + txtTH.Text;
Calling with the Class Method
Bitmap bmp = ClassWSThumb.GetWebSiteThumbnail(txtURL.Text, Int32.Parse(txtBW.Text),
Int32.Parse(txtBH.Text), Int32.Parse(txtTW.Text),
Int32.Parse(txtTH.Text));
bmp.Save(Server.MapPath("~") + "/thumbnail.bmp");
ImageBox.ImageUrl = "~/thumbnail.bmp";
Here is the class method code:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.IO;
namespace GetWebSiteThumb
{
public class ClassWSThumb
{
public static Bitmap GetWebSiteThumbnail(string Url, int BrowserWidth,
int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
{
return new WSThumb(Url, BrowserWidth, BrowserHeight,
ThumbnailWidth, ThumbnailHeight).GetWSThumb();
}
private class WSThumb
{
public WSThumb(string Url, int BW, int BH, int TW, int TH) {
__Url = Url;
__BrowserWidth = BW;
__BrowserHeight = BH;
__ThumbnailWidth = TW;
__ThumbnailHeight = TH;
}
private Bitmap __Bitmap = null;
private string __Url = null;
private int __ThumbnailWidth;
private int __ThumbnailHeight;
private int __BrowserWidth;
private int __BrowserHeight;
public string Url {
get{return __Url;}
set{__Url = value;}
}
public Bitmap ThumbnailImage {
get{return __Bitmap;}
}
public int ThumbnailWidth {
get{return __ThumbnailWidth;}
set{__ThumbnailWidth = value;}
}
public int ThumbnailHeight {
get {return __ThumbnailHeight;}
set {__ThumbnailHeight = value;}
}
public int BrowserWidth {
get{return __BrowserWidth;}
set{__BrowserWidth = value;}
}
public int BrowserHeight {
get{return __BrowserHeight;}
set{__BrowserHeight = value;}
}
public Bitmap GetWSThumb() {
ThreadStart __threadStart = new ThreadStart(_GenerateWSThumb);
Thread __thread = new Thread(__threadStart);
__thread.SetApartmentState(ApartmentState.STA);
__thread.Start();
__thread.Join();
return __Bitmap;
}
private void _GenerateWSThumb() {
WebBrowser __WebBrowser = new WebBrowser();
__WebBrowser.ScrollBarsEnabled = false;
__WebBrowser.Navigate(__Url);
__WebBrowser.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
while (__WebBrowser.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
__WebBrowser.Dispose();
}
private void WebBrowser_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e) {
WebBrowser __WebBrowser = (WebBrowser)sender;
__WebBrowser.ClientSize = new Size(this.__BrowserWidth, this.__BrowserHeight);
__WebBrowser.ScrollBarsEnabled = false;
__Bitmap = new Bitmap(__WebBrowser.Bounds.Width, __WebBrowser.Bounds.Height);
__WebBrowser.BringToFront();
__WebBrowser.DrawToBitmap(__Bitmap, __WebBrowser.Bounds);
if (__ThumbnailHeight != 0 && __ThumbnailWidth !=0)
__Bitmap = (Bitmap)__Bitmap.GetThumbnailImage(
__ThumbnailWidth, __ThumbnailHeight, null, IntPtr.Zero);
}
}
}
}
Here is the IHTTPHandler
method code:
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Reflection;
namespace GetWebSiteThumb
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class HandlerWSThumb : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
Bitmap thumb = null;
string url = null;
int bw = 800; int bh = 600; int tw = 0; int th = 0;
context.Response.ContentType = "image/jpeg";
if (context.Request["url"] != null)
{
if (context.Request["url"].ToString().ToLower().Contains("http://") ||
context.Request["url"].ToString().ToLower().Contains("https://"))
url = context.Request["url"].ToString();
else
url = "http://" + context.Request["url"].ToString();
}
if (context.Request["bw"] != null)
bw = Int32.Parse(context.Request["bw"].ToString());
if (context.Request["bh"] != null)
bh = Int32.Parse(context.Request["bh"].ToString());
if (context.Request["tw"] != null)
tw = Int32.Parse(context.Request["tw"].ToString());
if (context.Request["th"] != null)
th = Int32.Parse(context.Request["th"].ToString());
thumb = GetWebSiteThumbnail(url, bw, bh);
if (tw != 0 && th != 0)
thumb.GetThumbnailImage(tw, th, null, IntPtr.Zero).Save(
context.Response.OutputStream, ImageFormat.Jpeg);
else
thumb.Save(context.Response.OutputStream, ImageFormat.Jpeg);
thumb.Dispose();
}
public static Bitmap GetWebSiteThumbnail(string Url,
int BrowserWidth, int BrowserHeight)
{
WebsiteThumbnailImage thumbnailGenerator =
new WebsiteThumbnailImage(Url, BrowserWidth, BrowserHeight);
return thumbnailGenerator.GenerateWebSiteThumbnailImage();
}
private class WebsiteThumbnailImage
{
public WebsiteThumbnailImage(string Url,
int BrowserWidth, int BrowserHeight)
{
this.m_Url = Url;
this.m_BrowserWidth = BrowserWidth;
this.m_BrowserHeight = BrowserHeight;
}
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_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)
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);
}
}
public bool IsReusable
{
get { return false; }
}
}
}
Points of Interest
I learn that there are always three ways to do things: the right way, the wrong way, and the best way. I tried to cover the 3 of them ;) As an add-on, you could build a WebService method for returning the thumbnail. Maybe I will edit this article in the near future and put some code in the sample to accomplish it.
History
- Version 1.0: Upgrades and tips are welcome.
- Version 1.1: Just added a comment about converting the resulting BMP in the class method to JPEG, after a user asked me to do that.