iSkool.Net
Remember me 
[ Forgotten Password? ] [ Sign up ]
Blogs
jack
Blog Titles
Custom paging a datalist .Net 2.0 +
[ 5/5/2009 5:26:04 AM ]
Handling extensionless URLs
[ 6/24/2007 12:55:05 AM ]
Screen Shot Grabber
[ 3/3/2007 9:59:51 PM ]
Screen Shot Grabber

A friend of mine asked me to make him a little app that would take a screen shot of any URL and save it as a jpeg.

Hmmm, I thought, not having done very much with GDI and drawing classes and mostly developing web projects. I knew this would need a windows application to take the screen shot, so I set about trying to build this up.

Et Voila! Only version 1, but this one will take an inputted URL, produce a preview and then allow the user to resize and save the screen shot as a jpeg on their computer.



So, how to do...

First of all I found some cool GDI code on the .Net forums by clyde1. It was in C# so I first needed to convert it to VB and tweak a little.
The resulting class takes a screen shot of an input URL - resizes and produces a bitmap of the page.

*****

Imports Microsoft.VisualBasic
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Drawing.Drawing2D

Public Class Screenshot

Private screenWidth As Integer
Private screenHeight As Integer
Private browser As WebBrowser = New WebBrowser()

Public Sub New ( ByVal screenWidth As Integer , ByVal screenHeight As Integer )

Me .screenWidth = screenWidth

Me .screenHeight = screenHeight

browser.ScrollBarsEnabled = False

browser.Size = New Size(screenWidth, screenHeight)

End Sub

Public Function Fetch( ByVal url As String , ByVal width As Integer , ByVal height As Integer ) As Bitmap

browser.Navigate(url)

While browser.ReadyState <> WebBrowserReadyState.Complete

Application.DoEvents()

End While

Dim bitmap As Bitmap = New Bitmap(screenWidth, screenHeight)

Dim rectangle As Rectangle = New Rectangle(0, 0, screenWidth, screenHeight)

browser.DrawToBitmap(bitmap, rectangle)

Dim imgOutput As Image = bitmap

Dim screenshot As Bitmap = New Bitmap(width, height, imgOutput.PixelFormat)

Dim graphics As Graphics = Drawing.Graphics.FromImage(screenshot)

graphics.CompositingQuality = CompositingQuality.HighSpeed

graphics.SmoothingMode = SmoothingMode.HighSpeed

graphics.InterpolationMode = InterpolationMode.HighQualityBilinear

Dim rect As Rectangle = New Rectangle(0, 0, width, height)

graphics.DrawImage(imgOutput, rect)

Try

Return screenshot

Finally

bitmap.Dispose()

graphics.Dispose()

End Try

End Function

End Class

*****

Then to call this from the main form we add this to the event handler for the 'generate screen shot' button.
I then use Drawing.Image to convert the bitmap to a thumbnail image and show it in the picture box.

*****

Public Class Form1

Dim Mus As MyAppSettings

Private Sub btnSS_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSS.Click

lblSSInfo.Text = "Generating..."

lblSSInfo.ForeColor = Color.SlateGray

Dim y As Bitmap = GetBitmap(TxtUrl.Text)

' Save thumbnail and output it onto the webpage

Dim myCallBack As System.Drawing.Image.GetThumbnailImageAbort

myCallBack = New System.Drawing.Image.GetThumbnailImageAbort( AddressOf FunctionName)

'resize to thumnail

Dim mythumbnail As System.Drawing.Image

mythumbnail = y.GetThumbnailImage(308, 264, myCallBack, IntPtr.Zero)

PBSS.Image = mythumbnail

lblSSInfo.Text = "Generated"

lblSSInfo.ForeColor = Color.Firebrick

End Sub

Public Function GetBitmap( ByVal url As String )

Dim x As Screenshot = New Screenshot(800, 600)

Dim screenshot As Bitmap = x.Fetch(url, 800, 800)

Return screenshot

End Function

End Class

*****
Next we need to add the event handler for the "SaveScreen Shot" button. Again, I resize it according to user input and save to the chosen directory.

*****

Private Sub btnSave_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click

lblSaveInfo.Text = "saving..."

lblSaveInfo.ForeColor = Color.SlateGray

' generates the jpeg and resizes it

Dim y As Bitmap = GetBitmap(TxtUrl.Text)

' Save thumbnail and output it onto the webpage

Dim myCallBack As System.Drawing.Image.GetThumbnailImageAbort

myCallBack = New System.Drawing.Image.GetThumbnailImageAbort( AddressOf FunctionName)

'resize to thumnail

Dim mythumbnail As System.Drawing.Image

mythumbnail = y.GetThumbnailImage(txtWidth.Text, TxtHeight.Text, myCallBack, IntPtr.Zero)

If Not Txtname.Text = "" Then

mythumbnail.Save(lblSavePath.Text & "\" & Txtname.Text & ".jpg" , System.Drawing.Imaging.ImageFormat.Jpeg)

Else

mythumbnail.Save(lblSavePath.Text & "\" & "unknown.jpg" , System.Drawing.Imaging.ImageFormat.Jpeg)

End If

lblSaveInfo.Text = "saved"

lblSaveInfo.ForeColor = Color.Firebrick

Mus.IHeight = TxtHeight.Text

Mus.IWidth = txtWidth.Text

Mus.SavePath = lblSavePath.Text

Mus.Save()

End Sub

Public Function FunctionName() As Boolean

'This handles the getThumnailimageabort

Return False

End Function

*****

Another interesting piece of winForms programming I learnt here was the use of <UserScopedSetting()> _
These allow you to save users settings and I needed this to save the users prefered width and height as well as their prefered save path.

This is the class I used:

*****

Imports System.Configuration

Public Class MyAppSettings
Inherits ApplicationSettingsBase

<UserScopedSetting()> _

<DefaultSettingValue( "white" )> _

Public Property BackgroundColor() As Color

Get

BackgroundColor = Me ( "BackgroundColor" )

End Get

Set ( ByVal value As Color)

Me ( "BackgroundColor" ) = value

End Set

End Property

<UserScopedSetting()> _

<DefaultSettingValue( "C:\program files\" )> _

Public Property SavePath() As String

Get

SavePath = Me ( "SavePath" )

End Get

Set ( ByVal value As String )

Me ( "SavePath" ) = value

End Set

End Property

<UserScopedSetting()> _

<DefaultSettingValue( "267" )> _

Public Property IWidth() As String

Get

IWidth = Me ( "IWidth" )

End Get

Set ( ByVal value As String )

Me ( "IWidth" ) = value

End Set

End Property

<UserScopedSetting()> _

<DefaultSettingValue( "200" )> _

Public Property IHeight() As String

Get

IHeight = Me ( "IHeight" )

End Get

Set ( ByVal value As String )

Me ( "IHeight" ) = value

End Set

End Property

End Class

*****

I could then easily save values the user entered from the main form like so:-

Mus.IHeight = TxtHeight.Text
Mus.IWidth = txtWidth.Text
Mus.SavePath = lblSavePath.Text
Mus.Save()

----------------------------------------------

Next step is to create a section that allows for a multiple number of URLs to be entered and a jpeg produced for each one.
I used the tab control to show another page for this function [shown below]



Here's how...

All I needed to do was to allow the user to paste in csv into a textbox, then using the split function, I was able to create an array of successfully split URLs and saved jpegs. Here's the code for the event

******

Private Sub btnMultiSave_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMultiSave.Click

Dim aryUrls As Array

Dim i As Integer = 0

aryUrls = Split(TxtMultiURLs.Text, (vbCrLf))

For i = 0 To UBound(aryUrls)

'process each image

lblmultiInfo.Text = "saving..."

lblMultiInfo.ForeColor = Color.SlateGray

' generates the jpeg and resizes it

Dim z As Bitmap = GetBitmap((aryUrls(i)))

' Save thumbnail and output it onto the webpage

Dim myCallBack As System.Drawing.Image.GetThumbnailImageAbort

myCallBack = New System.Drawing.Image.GetThumbnailImageAbort( AddressOf FunctionName)

'resize to thumnail

Dim mythumbnail As System.Drawing.Image

mythumbnail = z.GetThumbnailImage(TxtMultiWidth.Text, TxtMultiHeight.Text, myCallBack, IntPtr.Zero)

Try

If Not TxtMultiName.Text = "" Then

mythumbnail.Save(lblMultiSavePath.Text & "\" & TxtMultiName.Text & "_" & i & ".jpg" , System.Drawing.Imaging.ImageFormat.Jpeg)

Else

mythumbnail.Save(lblMultiSavePath.Text & "\unkown_" & i & ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg)

End If

lblMultiInfo.Text = "saved"

lblMultiInfo.ForeColor = Color.Firebrick

Mus.IMultiHeight = TxtMultiHeight.Text

Mus.IMultiWidth = TxtMultiWidth.Text

Mus.MultiSavePath = lblMultiSavePath.Text

Mus.Save()

txtresults.Text = txtresults.Text + (aryUrls(i)) & vbCrLf

Catch ex As Exception

txtresults.Text = txtresults.Text + ex.ToString

lblMultiInfo.Text = "error"

End Try

Next

End Sub

*****
All comments gratefully received. Jack

*****




Rate this blog: 
Current rating:
-1010000
     Please login to rate this blog

comments 

Comments: No comments yet



Please login to make a comment