Скачать изображение под указателем мыши через WebBrowser - PullRequest
1 голос
/ 16 мая 2019

Я перехожу на Google Images с помощью элемента управления WebBrowser.Цель состоит в том, чтобы иметь возможность щелкнуть правой кнопкой мыши любое изображение, загрузить и заполнить фон 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 Ответ

1 голос
/ 16 мая 2019

Этот код позволяет использовать стандартный элемент управления WebBrowser для перехода на страницу поиска Google Image и выбора / загрузки изображения с помощью щелчка правой кнопкой мыши.

Чтобы проверить это, перетащите элемент управления WebBrowser и FlowLayoutPanel на форму и перейдите на страницу поиска изображений Google.

Что нужно знать:


Обратите внимание, что обработчик событий подключается по завершении текущего документа и удаляется при переходе браузера на другую страницу.Это предотвращает нежелательные звонки на событие DocumentCompleted.

Когда текущий Документ завершен, щелчок правой кнопкой мыши на изображении создает новый элемент управления PictureBox, который добавляется в FlowLayouPanel для презентации.

Код в обработчике щелчка мыши (Protected Sub OnHtmlDocumentClick()) определяет, является ли текущее изображение строкой Base64Encoded или внешним источником URI.
В первом случае он вызывает Convert.FromBase64String для преобразования строки в массив байтов, во втором случае используется WebClientкласс для загрузки изображения в виде байтового массива.

В обоих случаях массив затем передается другому методу (Private Function GetBitmapFromByteArray()), который возвращает изображение из массива, используя Image.FromStream() и MemoryStream инициализируется с помощью байтового массива.

Код здесь не выполняет нулевые проверки и подобные тесты на отказоустойчивость.Это должно, это зависит от вас.

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
...