İlk olarak .NET Framework'un en önemli konseptini hatırlatmakta fayda var. Web ile windows uygulamalarında aslında biz aynı Framework'ü kullanıyoruz. Yani eğer istersek windows forms uygulamalarında kullandığımız tüm kütüphaneleri ve objeleri web forms uygulamalarımızda da kullanabiliriz. Bir web sitesinin ekran görüntüsü almak için WinForms'da kullanabileceğimiz WebBrowser adında bir objemiz var.
Dim MyBrowser As New WebBrowser
MyBrowser.ScrollBarsEnabled = False
MyBrowser.Size = New Size(1027, 768)
MyBrowser.Navigate("http://depomp3.eu")
Dim myBitmap As New Bitmap(1024, 768)
Dim DrawRect As New Rectangle(0, 0, 1024, 768)
MyBrowser.DrawToBitmap(myBitmap, DrawRect)
Yukarıdaki kodumuz içerisinde yeni bir WebBrowser objesi yarattıktan sonra ekranın kenarlarında kaydırma çubuklarının gözükmemesi için ScrollBarsEnabled özelliğini False olarak düzenliyoruz. Bir sonraki adımda Browser (Tarayıcı) objemizin boyutunu 1024*768 yaparak sanki web sitesi o çözünürlükte bir ekranda açılmışmış gibi bir ortam yaratıyoruz. WebBrowser objesine ait .Navigate metoduna verdiğimiz parametre ile sitemizin yüklenmesini sağlıyoruz. Uygun resim ve çizim alanı değişkenlerimizi de tanımladıktan sonra yine WebBrowser objesine ait .DrawToBitmap metodunu kullanarak görüntüyü değişkenimize alıyoruz.
Tabi olay bu kadar kolay değil. Elimizdeki ilk sorun web sitesinin yüklenmesini beklemek zorunda olmamız. Bunun için kör bir döngü kullanacağız.
MyBrowser.Navigate(Me.URL)
While MyBrowser.ReadyState <> WebBrowserReadyState.Complete
Application.DoEvents()
End While
Kodumuzda WebBrowser objesinin ReadyState özelliğini kontrol ederek Complete olana kadar kısır bir döngüye sokuyoruz. Döngü içerisinde kullandığımız Application.DoEvents() kodu döngü süresince WebBrowser'daki yüklemenin kilitlenmemesini ve devam etmesini sağlayacak. Bir sonraki sorunumuz aslında çok daha kritik. WebBrowser objesi özünde bir COM objesi olduğu için Single Threaded bir Thread içerisinde çalıştırılması gerekiyor. Bu aslında biraz da işimize yarar, böylece tüm bu yükleme kodlarını başka bir Thread içerisine almış oluruz.
Dim NewTh As New Threading.Thread(AddressOf DoIt)
NewTh.SetApartmentState(Threading.ApartmentState.S TA)
NewTh.Start()
Yukarıda bir Thread tanımı yer alıyor. Bu tanım içerisinde en önemli nokta ikinci satırdaki kod. Yarattığımız Thread için SetApartmentState diyerek çalışma şeklini SingleThreadedApartment haline çeviriyoruz. Tüm sorunları aştık, geriye kaldı gelen ekran görüntüsünü uygun şekilde küçültme kodumuza. Bu işlem için çok farklı teknikler kullanılabilir, ben aşağıda bu tekniklerden birine ait kodu paylaşacağım. Makalemizin esas konusu bu olmadığı için detaya girmeyeceğim.
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)
Şimdi gelin tüm bu kodları birleştirerek bir Class yapısı içerisinde projelerimizde kullanacağımız kodumuzu inceleyelim.
Kod:
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
Yarattığımız iki classtan biri olan GetImage programcıdan alacağı ekran görüntüsüne ait çözünürlük bilgilerini ve geri döndüreceği resmin boyut bilgilerini alıyor. Aldığı bilgiler çerçevesinde ekran görüntüsünün alınması sonrasında da görüntünün istenen boyuta küçültülmesini sağlayacak. WebPageBitmap class'ımız ise ekran görüntüsünün alınmasından ve sonrasında da tekrar boyutlandırılmasında sorumlu. Tabi tüm bu işlemleri ayrı bir Thread içerisinde yapmamız gerektiğinden bahsetmiştik. Şimdi de gelin yukarıdaki Class'ımızı sayfamızda nasıl kullanabileceğimize bakalım.
Kod:
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.S TA)
NewTh.Start()
While NewTh.ThreadState = Threading.ThreadState.Running
End While
Image1.ImageUrl = TextBox1.Text.Replace(".", "_") & ".jpg"
End Sub
Kod:
Sub DoIT()
Try
Dim thumb As New GetSiteThumbnail.GetImage("http://" & TextBox1.Text, 1024, 768, 320, 240)
Dim x As System.Drawing.Bitmap = thumb.GetBitmap()
x.Save(Server.MapPath(".") & "\" & TextBox1.Text.Replace(".", "_") & ".jpg")
Catch ex As Exception
Dim y As System.IO.StreamWriter = System.IO.File.CreateText("C:\Inetpub\wwwroot\scre eny\error.txt")
y.WriteLine(ex.Message & vbCrLf & ex.Source)
y.Flush()
y.Close()
Finally
End Try
End Sub
End Class
Code-Behind dosyamızın kodunu yukarda inceleyebilirsiniz. Button1'e tıklandığında uygun Thread'i yaratarak DoIT Sub'ını çalıştıracağı şekilde hazırlıyoruz. Basit bir şekilde Thread'in bitmesini beklemek için yine kısır bir döngü kullanarak ThreadState durumunu kontrol ettik. Ekran görüntüsü alındığı gibi kullanıcıya göstermek için biraz kullanıcıyı bekletmemiz gerekecek. Eğer siz bir AJAX web sitesi hazırlıyorsanız ekran görüntüsünün alınmasını beklemektense bir AJAX Timer ile durumu kontrol edip kullanıcıya bilgi verebilirsiniz.