How do I create cached image of a webpage. I just wanted to create a thumbnail of a webpage based on URL. There is no way, you would find the right stuff to do so. I found
. He has explained the technique very well. Described his search for such code. He wrote on his own. There are a very few people got it
. So here is the code, took me a lot of time to get it working. Read through the sample I added here very carefully before you copy the code as is. I tried my best to write all comments to make it easy readable.
Tried it in all possible ways to make it successful the way I wanted. This code works awesome but I wanted to use System.drawing very well to make it work. There is no way I could find to do this without using Win32 Api. Apart from that, I need to add the axWebBrowser control and it needs to be visible on form in order to find the image of the web page. Then how do I do it on the fly on my website. There must be a way to create a thumbnail from webpage with out adding ActiveX controls....
Good Luck!! Let me know if this works for you.
'*************************************************************************
'This is main form Class where you will add the
basic functions.
'*************************************************************************
Imports
SHDocVw ' Import the shdocvw.dll from Widnows\System32 folder.
Imports
mshtml
' Import the mshtml.dll from Widnows\System32 folder.
Imports
System.Runtime.InteropServices
' Need this as we added above two as Interop
Imports
System.Windows.Forms
Public
Class Form1
Private
Sub Form1_Load(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles MyBase.Load
'Add the axWebBrowser control
from SHDocVw library to your form name it as axWebBrowser
'Add the Event Handler as DocumentComplete, because
we need to capture screen image when document is completely loaded.
AddHandler axWebBrowser.DocumentComplete, AddressOf
Me.OnDocumentComplete
End
Sub
Private
Sub OnDocumentComplete(ByVal
sender As Object,
ByVal e As AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent)
Dim document As IHTMLDocument2 =
CType(Me.axWebBrowser.Document,
IHTMLDocument2)
If Not (document Is
Nothing) Then
Dim element As IHTMLElement
= CType(document.body, IHTMLElement)
If Not (element
Is Nothing) Then
Dim render As
IHTMLElementRender = CType(element, IHTMLElementRender)
If Not (render
Is Nothing) Then
' Using
Dim graphics
As Graphics = Me.pictureBox.CreateGraphics
Try
Dim hdcDestination
As IntPtr = graphics.GetHdc
render.DrawToDC(hdcDestination)
Dim hdcMemory
As IntPtr = gdi32.CreateCompatibleDC(hdcDestination)
Dim bitmap As IntPtr = gdi32.CreateCompatibleBitmap(hdcDestination,
Me.axWebBrowser.ClientRectangle.Width,
Me.axWebBrowser.ClientRectangle.Height)
If
Not (bitmap = IntPtr.Zero) Then
Dim
hOld As IntPtr = CType(gdi32.SelectObject(hdcMemory,
bitmap), IntPtr)
gdi32.BitBlt(hdcMemory, 0, 0, Me.axWebBrowser.ClientRectangle.Width,
Me.axWebBrowser.ClientRectangle.Height, hdcDestination, 0, 0,
CType(gdi32.TernaryRasterOperations.SRCCOPY, Integer))
gdi32.SelectObject(hdcMemory, hOld)
gdi32.DeleteDC(hdcMemory)
graphics.ReleaseHdc(hdcDestination)
'Add a PictureBox control to your form,
named pictureBox. This way you can
'see the image immediately after it is generated. You can save to
FS using Bitmap.Save method.
Me.pictureBox.Image
= Image.FromHbitmap(bitmap)
End
If
Finally
'You must dispose Graphics Object for better use.
CType(graphics,
IDisposable).Dispose()
End
Try
End If
End If
End If
End
Sub
Private
Sub Button1_Click(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles Button1.Click
' Add a button to you
form named Button1.
'
This way we can control when we want to start Browsing.
'
Select the URI to be browsed here.
Me.axWebBrowser.Navigate(New Uri("http://www.google.com"))
End
Sub
End
Class
'*************************************************************************
'This class for dummy for calling GDI Functions from Win32
Api.
'So that you can encapsulate whole GDI work outside.
'*************************************************************************
Public
Class gdi32
' I copied
all the signatures in this class from http://www.pinvoke.net
Public
Declare Function
DeleteDC Lib "gdi32.dll"
(ByVal hdc As
IntPtr) As Boolean
Public
Declare Function
SelectObject Lib "gdi32.dll"
(ByVal hdc As
IntPtr, ByVal hgdiobj As
IntPtr) As IntPtr
Public
Declare Function
CreateCompatibleDC Lib
"gdi32" (ByVal hDC
As IntPtr) As IntPtr
Public
Declare Function
CreateCompatibleBitmap Lib
"gdi32" (ByVal hDC
As IntPtr, ByVal nWidth
As Integer, ByVal
nHeight As Integer)
As IntPtr
Public
Declare Function
BitBlt Lib "gdi32"
(ByVal hDestDC As
IntPtr, ByVal x As
Integer, ByVal
y As Integer,
ByVal nWidth As
Integer, ByVal
nHeight As Integer,
ByVal hSrcDC As
IntPtr, ByVal xSrc As
Integer, ByVal
ySrc As Integer,
ByVal dwRop As
Integer) As Integer
Enum
TernaryRasterOperations As
Integer
SRCCOPY = 13369376 'dest
= source
SRCPAINT = 15597702 'dest = source
OR dest
SRCAND = 8913094
'dest = source AND dest
SRCINVERT = 6684742 'dest = source
XOR dest
SRCERASE = 4457256 'dest
= source AND (NOT dest )
NOTSRCCOPY = 3342344 'dest = (NOT
source)
NOTSRCERASE = 1114278 'dest = (NOT src)
AND (NOT dest)
MERGECOPY = 12583114 'dest = (source
AND pattern)
MERGEPAINT = 12255782 'dest = (NOT source)
OR dest
PATCOPY = 15728673 'dest
= pattern
PATPAINT = 16452105 'dest = DPSnoo
PATINVERT = 5898313 'dest = pattern
XOR dest
DSTINVERT = 5570569 'dest = (NOT
dest)
BLACKNESS = 66
'dest = BLACK
WHITENESS = 16711778 'dest = WHITE
End
Enum
End
Class
'Check out Alan Dean's explaination, because I don;t get
it. He is smarter than me, so I just believed that it works.
<Guid("3050f669-98b5-11cf-bb82-00aa00bdce0b"), System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown),
System.Runtime.InteropServices.ComVisible(True),
System.Runtime.InteropServices.ComImport()> _
Interface
IHTMLElementRender
Sub
DrawToDC(<System.Runtime.InteropServices.In()> ByVal
hDC As IntPtr)
Sub
SetDocumentPrinter(<System.Runtime.InteropServices.In(), System.Runtime.InteropServices.MarshalAs(UnmanagedType.BStr)>
ByVal bstrPrinterName As
String, <System.Runtime.InteropServices.In()>
ByVal hDC As IntPtr)
End
Interface