通过WebBrowser在鼠标指针下下载图像

时间:2019-05-16 10:27:37

标签: vb.net winforms webbrowser-control

我正在使用WebBrowser控件导航到Google图片。目的是能够右键单击任何图像,然后下载并填充PictureBox背景。

我有自己的ContextMenuStrip,上面有“复制”,并且禁用了内置的上下文菜单。

我遇到的问题是,CurrentDocument.MouseMove返回的坐标始终相对于第一个(左上)图像。
因此,如果我想要的图像是页面上的第一张图像,则我的代码可以正常工作,但是单击任何其他图像始终会返回第一张图像的坐标。

似乎坐标是相对于每个图像而不是页面的。

Private WithEvents CurrentDocument As HtmlDocument
Dim MousePoint As Point
Dim Ele As HtmlElement

Private Sub Google_covers_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    WebBrowser1.IsWebBrowserContextMenuEnabled = False
    WebBrowser1.ContextMenuStrip = ContextMenuStrip1
End Sub

Private Sub WebBrowser1_Navigated(sender As Object, e As WebBrowserNavigatedEventArgs) Handles WebBrowser1.Navigated
    CurrentDocument = WebBrowser1.Document

End Sub
Private Sub CurrentDocument_MouseMove(sender As Object, e As HtmlElementEventArgs) Handles CurrentDocument.MouseMove
    MousePoint = New Point(e.MousePosition.X, e.MousePosition.Y)
    Me.Text = e.MousePosition.X & " | " & e.MousePosition.Y
End Sub

Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
    Ele = CurrentDocument.GetElementFromPoint(MousePoint)
    If Ele.TagName = "IMG" Then
        CopyToolStripMenuItem.Visible = True
    Else
        CopyToolStripMenuItem.Visible = False
    End If
End Sub

Private Sub CopyToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CopyToolStripMenuItem.Click
    Dim ToImg = Ele.GetAttribute("src")
    mp3_row_edit.PictureBox1.BackgroundImage = New System.Drawing.Bitmap(New IO.MemoryStream(New System.Net.WebClient().DownloadData(ToImg)))
    ToImg = Nothing
End Sub

1 个答案:

答案 0 :(得分:1)

此代码允许使用标准的WebBrowser控件导航到Google图片搜索页面,并通过右键单击鼠标选择/下载图片。

要对其进行测试,请将WebBrowser控件和FlowLayoutPanel放在窗体上,然后导航到Google图片搜索页。

须知:


请注意,当完成当前文档时,将连接事件处理程序,并在浏览器导航到另一个页面时将其删除。这样可以防止意外调用DocumentCompleted事件。

当前文档完成后,在图像上用鼠标右键单击,将创建一个新的PictureBox控件,该控件将添加到FlowLayouPanel中进行演示。

鼠标单击处理程序( Protected Sub OnHtmlDocumentClick() )中的代码检测当前图像是 Base64Encoded 字符串还是外部源 URI
在第一种情况下,它调用Convert.FromBase64String将字符串转换为Byte数组,在第二种情况下,它使用 WebClient 类将图像下载为Byte数组。

在两种情况下,然后将数组传递给另一个方法( Private Function GetBitmapFromByteArray() ),该方法使用 Image.FromStream() 从数组中返回图像和 MemoryStream 并用Byte数组初始化。

此处的代码未执行空值检查和类似的防故障测试。应该,这取决于您。

Public Class frmBrowser
    Private WebBrowserDocumentEventSet As Boolean = False
    Private base64Pattern As String = "base64,"

    Private Sub frmBrowser_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        WebBrowser1.ScriptErrorsSuppressed = True
        WebBrowser1.IsWebBrowserContextMenuEnabled = False
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
        If WebBrowser1.ReadyState = WebBrowserReadyState.Complete AndAlso WebBrowserDocumentEventSet = False Then
            WebBrowserDocumentEventSet = True
            AddHandler WebBrowser1.Document.MouseDown, AddressOf OnHtmlDocumentClick
        End If
    End Sub

    Protected Sub OnHtmlDocumentClick(sender As Object, e As HtmlElementEventArgs)
        Dim currentImage As Image = Nothing

        If Not (e.MouseButtonsPressed = MouseButtons.Right) Then Return
        Dim source As String = WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).GetAttribute("src")

        If source.Contains(base64Pattern) Then
            Dim base64 As String = source.Substring(source.IndexOf(base64Pattern) + base64Pattern.Length)
            currentImage = GetBitmapFromByteArray(Convert.FromBase64String(base64))
        Else
            Using wc As WebClient = New WebClient()
                currentImage = GetBitmapFromByteArray(wc.DownloadData(source))
            End Using
        End If

        Dim p As PictureBox = New PictureBox() With {
            .Image = currentImage,
            .Height = Math.Min(FlowLayoutPanel1.ClientRectangle.Height, FlowLayoutPanel1.ClientRectangle.Width)
            .Width = .Height,
            .SizeMode = PictureBoxSizeMode.Zoom
        }
        FlowLayoutPanel1.Controls.Add(p)
    End Sub

    Private Sub WebBrowser1_Navigating(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating
        If WebBrowser1.Document IsNot Nothing Then
            RemoveHandler WebBrowser1.Document.MouseDown, AddressOf OnHtmlDocumentClick
            WebBrowserDocumentEventSet = False
        End If
    End Sub

    Private Function GetBitmapFromByteArray(imageBytes As Byte()) As Image
        Using ms As MemoryStream = New MemoryStream(imageBytes)
            Return DirectCast(Image.FromStream(ms).Clone(), Image)
        End Using
    End Function
End Class