现在的位置: 首页 > 综合 > 正文

How to take screenshot (thumbnail) of a web site with ASP.NET 2.0?

2012年08月01日 ⁄ 综合 ⁄ 共 7171字 ⁄ 字号 评论关闭
 

Introduction

Moslty in site directory web sites there is a need to have the thumbnail image of each web site. Of course this feature can be needed in a wide range of projects handling with high amount of web sites.

Capturing screenshots with Windows application are very easy but how to capture a web sites screenshot? Imagine we load the given web site in our application and take a screenshot of it. To load the needed web site we can use WebBrowser component of .NET Framework 2.0 and use .DrawToBitmap method to get a bitmap picture of current web site. The scenario works well in Windows applications but how we do this in a web site?

The Idea

Never forget that ASP.NET and Windows Forms applications are all about .NET Framework. So theoretically we can do all the things in an ASP.NET application like we do in Windows Forms. The idea behind our solution will be to initialize a hidden WebBrowser component and load our web site inside it to be able to get screenshot. Of course we will fight against many further problem.

Using WebBrowser Component

Dim MyBrowser As New WebBrowser 
MyBrowser.ScrollBarsEnabled = False
MyBrowser.Size = New Size(1027, 768)
MyBrowser.Navigate(”http://www.deveload.com”)
Dim myBitmap As New Bitmap(1024, 768)
Dim DrawRect As New Rectangle(0, 0, 1024, 768)
MyBrowser.DrawToBitmap(myBitmap, DrawRect)

After defining our WebBrowser variable we set some properties like ScrollBarsEnabled to false and the size of our browser. We call navigate method and open the web site “www.deveload.com”. On next we define our BitMap variable, drawing surface and use DrawToBitmap method to get our screenshot.

It seems all ok but if you run this application you will get many errors. First problem is that we didn’t wait for the web site to get loaded. We just took an instant screenshot after calling the web site. Normally we should wait for the web site to be loaded totally.

MyBrowser.Navigate(Me.URL)
While MyBrowser.ReadyState <> WebBrowserReadyState.Complete
Application.DoEvents()
End While

After starting to load our web site we will just take a dummy loop to wait the web site to be loaded totally. Why we are using Application.DoEvents() is a trick I will explain later on. An other problem is that our WebBrowser control is actually a COM object. We need to be in a Single Threaded process to be able to use WebBrowser freely. All of our screen taking code should be handled in an independent thread.

Dim NewTh As New Threading.Thread(AddressOf DoIt)
NewTh.SetApartmentState(Threading.ApartmentState.STA)
NewTh.Start()

Let’s get back to our last code where we used a loop to wait our WebBrowser control. Think about it again. We have got a single thread and going in a loop to wait our web site to load. Normally our loop would lock our application and thread would wait for the loop to finish to be able to render our WebBrowser component further on. So why isn’t that happening like that? Application.DoEvents() is the answer. This method will let us to render our control while our loop is in process.

Creating Thumbnail Image

Dim imgOutput As System.Drawing.Image = myBitmap
Dim oThumbNail As System.Drawing.Image = New Bitmap(twidth, theight, & _
imgOutput.PixelFormat)
Dim g As Graphics = Graphics.FromImage(oThumbNail)
g.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
g.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBilinear
Dim orectangle As Rectangle = New Rectangle(0, 0, twidth, theight)
g.DrawImage(imgOutput, orectangle)

In the code above we define imgOutput and assign our original image to it, which is named myBitmap. twidth, theight are our target size variables. We create a grapics object from a dummy image having our destination size. We set some properties of graphics object and make the render with DrawImage method.

Final Class

Collapse
Imports System 
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Windows.Forms
Imports System.Diagnostics

Namespace GetSiteThumbnail

Public Class GetImage
Private S_Height As Integer
Private S_Width As Integer
Private F_Height As Integer
Private F_Width As Integer
Private MyURL As String

Property ScreenHeight() As Integer
Get
Return S_Height
End Get
Set(ByVal value As Integer)
S_Height = value
End Set
End Property

Property ScreenWidth() As Integer
Get
Return S_Width
End Get
Set(ByVal value As Integer)
S_Width = value
End Set
End Property

Property ImageHeight() As Integer
Get
Return F_Height
End Get
Set(ByVal value As Integer)
F_Height = value
End Set
End Property

Property ImageWidth() As Integer
Get
Return F_Width
End Get
Set(ByVal value As Integer)
F_Width = value
End Set
End Property

Property WebSite() As String
Get
Return MyURL
End Get
Set(ByVal value As String)
MyURL = value
End Set
End Property

Sub New(ByVal WebSite As String, ByVal ScreenWidth As Integer, &_
ByVal ScreenHeight As Integer, ByVal ImageWidth As Integer,&_
ByVal ImageHeight As Integer)
Me.WebSite = WebSite
Me.ScreenWidth = ScreenWidth
Me.ScreenHeight = ScreenHeight
Me.ImageHeight = ImageHeight
Me.ImageWidth = ImageWidth
End Sub

Function GetBitmap() As Bitmap
Dim Shot As New WebPageBitmap(Me.WebSite, Me.ScreenWidth, &_
Me.ScreenHeight)
Shot.GetIt()
Dim Pic As Bitmap = Shot.DrawBitmap(Me.ImageHeight, &_
Me.ImageWidth)
Return Pic
End Function
End Class

Class WebPageBitmap
Dim MyBrowser As WebBrowser
Dim URL As String
Dim Height As Integer
Dim Width As Integer

Sub New(ByVal url As String, ByVal width As Integer, &_
ByVal height As Integer)
Me.Height = height
Me.Width = width
Me.URL = url
MyBrowser = New WebBrowser
MyBrowser.ScrollBarsEnabled = False
MyBrowser.Size = New Size(Me.Width, Me.Height)
End Sub

Sub GetIt()
MyBrowser.Navigate(Me.URL)
While MyBrowser.ReadyState <> WebBrowserReadyState.Complete
Application.DoEvents()
End While
End Sub

Function DrawBitmap(ByVal theight As Integer, &_
ByVal twidth As Integer) As Bitmap
Dim myBitmap As New Bitmap(Width, Height)
Dim DrawRect As New Rectangle(0, 0, Width, Height)
MyBrowser.DrawToBitmap(myBitmap, DrawRect)
Dim imgOutput As System.Drawing.Image = myBitmap
Dim oThumbNail As System.Drawing.Image = New Bitmap(twidth, &_
theight, imgOutput.PixelFormat)
Dim g As Graphics = Graphics.FromImage(oThumbNail)
g.CompositingQuality = Drawing2D.CompositingQuality.HighSpeed
g.SmoothingMode = Drawing2D.SmoothingMode.HighSpeed
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBilinear
Dim orectangle As Rectangle = New Rectangle(0, 0, twidth, theight)
g.DrawImage(imgOutput, orectangle)
Try
Return oThumbNail
Catch ex As Exception
Finally
imgOutput.Dispose()
imgOutput = Nothing
MyBrowser.Dispose()
MyBrowser = Nothing
End Try
End Function
End Class

End Namespace

How to use the code?

Partial Class _Default 
Inherits System.Web.UI.Page

Protected Sub Button1_Click(ByVal sender As Object, &_
ByVal e As System.EventArgs) Handles Button1.Click
Dim NewTh As New Threading.Thread(AddressOf DoIt)
NewTh.SetApartmentState(Threading.ApartmentState.STA)
NewTh.Start()
End Sub

Sub DoIT()
Try
Dim thumb As New GetSiteThumbnail.GetImage("http://www.deveload.com/",&_
1024, 768, 320, 240)
Dim x As System.Drawing.Bitmap = thumb.GetBitmap()
x.Save("C:/Inetpub/wwwroot/screeny/deveload.jpg")
Catch ex As Exception
Dim y As System.IO.StreamWriter = System.IO.File.CreateText("C:/Inetpub/wwwroot/screeny/error.txt")
y.WriteLine(ex.Message & vbCrLf & ex.Source)
y.Flush()
y.Close()
End Try
End Sub
End Class

The code above is creating an instance of our Class and trying to get a screenshot. If any error happens it will create a text file and write the error inside it. Do not forget that the class DoIT is working as a separated thread.

Conclusion

The system is well working on 90% of web sites. Some web sites loading external daya by AJAX of Flash after the complete of web page load cycle will not work on this system.

About Daron Yöndem

Daron Yöndem has been a professional web developer since 2002 and Windows Interface developer since 1998, and is working with VB.NET and ASP.Net since early 2002. He has been working with VB 3.0, 4.0 and 6.0 since 1998.

He is the founder of DEVELOAD Software & Design, a recognized leader in web-enabled application development with a proven track record in Turkey since 2003. The company is specialized in custom online applications.

Click here to view Daron Yöndem's online profile.

Google

抱歉!评论已关闭.