我正在使用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
答案 0 :(得分:1)
此代码允许使用标准的WebBrowser控件导航到Google图片搜索页面,并通过右键单击鼠标选择/下载图片。
要对其进行测试,请将WebBrowser控件和FlowLayoutPanel放在窗体上,然后导航到Google图片搜索页。
须知:
HtmlDocument
主页中的子文档之一完成时,都会引发此事件。因此,它可以被多次提出。我们需要检查WebBrowser.ReadyState = WebBrowserReadyState.Complete
。Base64Encoded
字符串和经典的 src=[URI]
< / strong>格式。我们需要准备好实现两者。 e.ClientMousePosition
或e.OffsetMousePosition
引用的绝对坐标或相对坐标来表示鼠标单击的位置。请注意,当完成当前文档时,将连接事件处理程序,并在浏览器导航到另一个页面时将其删除。这样可以防止意外调用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