VB.NET - Saving Image from webbrowser control

Asked By B. Blok on 15-Jun-08 08:03 AM
Hi,

I was wondering how I could save an image from a webbrowser control to a file or picturebox. this attempt fails with an "out of memory":

webbrowser.navigate("http://example.com/image.php?some stuff here&.gif")
Dim objWriter As New System.IO.StreamWriter(C:\Image.bmp)
objWriter.Write(WebBrowser.DocumentText)
objWriter.Close()

This works:

webbrowser.navigate("http://example.com/image.php?some stuff here&.gif")
webbrowser.ShowSaveAsDialog()

however, the second requires user interaction and that is _NOT_ what I want.

The picture is on a website which ask for certain cookies. Those cookies are in the webbrowser component. So I need to use the webbrowser component to download this image.
Can anyone help me?

Hello

alice johnson replied to B. Blok on 15-Jun-08 12:05 PM

Hi try this way

Prerequisites: Button1, Label1 and ProgressBar1 on Form1.

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        Dim file As String = "http://URL/image.jpg"  'Specify URL of an image

        Dim request As System.Net.WebRequest = System.Net.HttpWebRequest.Create(file)

        Dim response As System.Net.HttpWebResponse = request.GetResponse()

        Dim stream As System.IO.Stream = response.GetResponseStream()

        ' Get the length of the content

        Dim length As Integer = response.ContentLength

        ' Set the maximum length of the progress bar.

        ProgressBar1.Maximum = length

        ' Create a temporary array for the content of the file.

        Dim bytes(length) As Byte

        ' Get all bytes of the content and advance the progress bar.

        For i As Integer = 0 To length - 1

            bytes(i) = stream.ReadByte()

            ProgressBar1.Value = i

            Label1.Text = i.ToString + "Bytes Downloaded"

            Application.DoEvents()

        Next

        ' Write the content to the local file.

        Using output As IO.Stream = System.IO.File.Create("D:\newImg.jpg")

            output.Write(bytes, 0, bytes.Length)

        End Using

    End Sub

rePly

alice johnson replied to B. Blok on 15-Jun-08 12:10 PM

You can use the Internet Transfer Control to download an image from a URL and save it to a file without user interaction.

Dim tData() As Byte
Dim iFile As Integer
Dim sURL As String

sURL = "http://forums.devx.com/images/statusicon/thread_hot.jpg"
iFile = FreeFile
tData = ctlInet.OpenURL(sURL, icByteArray)
Open "d:\path\file.jpg" For Binary As iFile 
Put #iFile, , tData() 
Close iFile 
hi please go through this link:
http://forums.devx.com/showthread.php?t=149977&goto=nextoldest
-------------------------------------------------------------------------------------------------------------------------------------

Step 1. Get all img elements:      

Dim theElementCollection As HtmlElementCollection = WebBrowser1.Document.GetElementsByTagName("img")

 

Step 2. Get each URL of img element:     

        For Each curElement As HtmlElement In theElementCollection

            Dim imgURL As String = curElement.GetAttribute("src").ToString

        Next

 

Step 3. Then download image file using HttpWebRequest and HttpWebResponse classes.

Public Class Form1

 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        WebBrowser1.Navigate("http://msdn2.microsoft.com/en-us/default.aspx")

    End Sub

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

   

        '<img src="http://www.google.co.uk/logos/halloween07.gif">

 

        Dim theElementCollection As HtmlElementCollection = Me.WebBrowser1.Document.GetElementsByTagName("img")

        Dim n As Int32 = theElementCollection.Count

        Dim index As Int32 = 1

        For Each curElement As HtmlElement In theElementCollection

 

            'MessageBox.Show(curElement.GetAttribute("src").ToString)

            Dim imgURL As String = curElement.GetAttribute("src").ToString

            Dim request As System.Net.WebRequest = System.Net.HttpWebRequest.Create(imgURL)

            Dim response As System.Net.HttpWebResponse = request.GetResponse()

            Dim stream As System.IO.Stream = response.GetResponseStream()

            ' Get the length of the content

            Dim length As Integer = response.ContentLength

 

            Dim bytes(length) As Byte

 

            For i As Integer = 0 To length - 1

                bytes(i) = stream.ReadByte()

                Application.DoEvents()

            Next

            ' Save each image in turn.

            Using output As IO.Stream = System.IO.File.Create("D:\Image" + index.ToString + ".jpg")

                output.Write(bytes, 0, bytes.Length)

            End Using

            index += 1

        Next

 

    End Sub

End Class

You do not need the webbrowser control to handle cookies.

Peter Bromberg replied to B. Blok on 15-Jun-08 12:34 PM

Use the CookieContainer class to attach your cookie(s) to a WebClient request for the image. You can use the DownloadData method, which returns a byte array that you can save directly to the filesystem.

You can find plenty of sample code on how to use either WebClient or HttpWebRequest/WebResponse and the CookieContainer class.


Using WebBrowser_OnDocumentComplete event
sundar k replied to B. Blok on 15-Jun-08 12:34 PM

In webbrowser OnDocumentComplete event, you can render the graphic image into a picturebox control and can save the content of picturebox to a physical file,

Private Sub OnDocumentComplete(ByVal sender As Object, ByVal e As AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent)
  Dim document As IHTMLDocument2 = CType(Me.axWebBrowser1.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.pictureBox1.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.axWebBrowser1.ClientRectangle.Width, Me.axWebBrowser1.ClientRectangle.Height)
          If Not (bitmap = IntPtr.Zero) Then
            Dim hOld As IntPtr = CType(GDI32.SelectObject(hdcMemory, bitmap), IntPtr)
            GDI32.BitBlt(hdcMemory, 0, 0, Me.axWebBrowser1.ClientRectangle.Width, Me.axWebBrowser1.ClientRectangle.Height, hdcDestination, 0, 0, CType(GDI32.TernaryRasterOperations.SRCCOPY, Integer))
            GDI32.SelectObject(hdcMemory, hOld)
            GDI32.DeleteDC(hdcMemory)
            graphics.ReleaseHdc(hdcDestination)
            Me.pictureBox.Image = Image.FromHbitmap(bitmap)
          End If
        Finally
          CType(graphics, IDisposable).Dispose()
        End Try
      End If
    End If
  End If
End Sub

Please check the below link for detailed explanation about the how the above code works,

http://www.developerfusion.co.uk/show/4712/

hope it helps!

Try this..............
Sagar P replied to B. Blok on 15-Jun-08 11:56 PM

If the WebBrowser control is obscured in some fashion then you still get the original copy. There is, unfortunately, a further problem which is that the copy made is not persistent. This means that if the PictureBox which contains the copy is obscured in some fashion, then the copy needs to be made a second time. Furthermore, the copied image is not available via the Image property of the PictureBox which means that you cannot call the Save() method, for example, to save the image to disk. In order to set the Image property, we need to create and set a persistent bitmap. To do this we need to resort to the Win32 API again

private void OnDocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
    IHTMLDocument2 document = (IHTMLDocument2) this.axWebBrowser1.Document;
    if (document != null)
    {
          IHTMLElement element = (IHTMLElement) document.body;
          if (element != null)
          {
              IHTMLElementRender render = (IHTMLElementRender) element;
              if (render != null)
              {
                    using (Graphics graphics = this.pictureBox1.CreateGraphics())
                    {
                        IntPtr hdcDestination = graphics.GetHdc();
                        render.DrawToDC(hdcDestination);
                        IntPtr hdcMemory = GDI32.CreateCompatibleDC(hdcDestination);
                        IntPtr bitmap = GDI32.CreateCompatibleBitmap(
                              hdcDestination, 
                              this.axWebBrowser1.ClientRectangle.Width, this.axWebBrowser1.ClientRectangle.Height
                              );
             
                        if (bitmap != IntPtr.Zero)
                        {
                              IntPtr hOld = (IntPtr) GDI32.SelectObject(hdcMemory, bitmap);
                              GDI32.BitBlt(
                                  hdcMemory,
                                  0, 0,
                                  this.axWebBrowser1.ClientRectangle.Width, this.axWebBrowser1.ClientRectangle.Height,
                                  hdcDestination,
                                  0, 0,
                                  (int) GDI32.TernaryRasterOperations.SRCCOPY
                                  );
                              GDI32.SelectObject(hdcMemory, hOld);
                              GDI32.DeleteDC(hdcMemory);
                              graphics.ReleaseHdc(hdcDestination);
         
                              this.pictureBox.Image = Image.FromHbitmap(bitmap);
                        }
                    }
              }
          }
    }
}

Just go thr this link for more details;

http://www.developerfusion.co.uk/show/4712/

Best Luck!!!!!!!!!!!!!!!
Sujit.

Saving Image from webbrowser control
Swapnil Salunke replied to B. Blok on 16-Jun-08 12:44 AM

Hello  B. Blok

It can be done in this way

Private Sub Form_Load()
If doneFileSaveThing("http://forums.devx.com/images/statusicon/thread_hot.jpg") Then
MsgBox "FileSave "
Else
MsgBox "File ''Not'' Save "
End If
End Sub
Public Function doneFileSaveThing(sURL As String) As Boolean
Dim iFile As Integer
If Not FileExists2("d:\path\file.jpg") Then GoTo ****
On Error GoTo ****
iFile = FreeFile
tData = ctlInet.OpenURL(sURL, icByteArray)
Open "d:\path\file.jpg" For Binary As iFile
Put #iFile, , tData()
Close iFile
doneFileSaveThing = True
Exit Function
****:
doneFileSaveThing = False
End Function
Public Function FileExists(ByVal sFileName As String) As Boolean
    Dim sFile As String
    On Error Resume Next
    sFile = Dir$(sFileName)
    If (Len(sFile) > 0) And (Err = 0) Then FileExists = True Else FileExists = False
End Function
Public Function FileExists2(ByRef sPath As String, Optional ByRef lFileSize As Long) As Boolean
   On Error Resume Next
   lFileSize = FileLen(sPath)
   FileExists = (Err = 0)
End Function
Public Function FileExists3(filespec) As Boolean
Dim RFS
Set RFS = CreateObject("Scripting.FileSystemObject")
FileExists = RFS.FileExists(filespec)
Set RFS = Nothing
End Function



Go through this links ot may help you
   http://forums.devx.com/showthread.php?t=149977&goto=nextoldest
   http://www.developerfusion.co.uk/show/4712/
Happy Coding takecare
 
thanks
B. Blok replied to Swapnil Salunke on 16-Jun-08 12:17 PM
thank you all for your answers! The solutions suggested were ones I already found, but none of them really work for me, since they do not deal with the cookies that are being used in the webbrowser object. However, I will work around this by loggin in again with the httprequest / webrequest and then perform the action.

I thank you all for your replies and they are still quite useful, since they are a great summary!

Thank you all!