webView2コントロールの画面キャプチャをしたくて(非同期版)
先日の「webView2コントロールの画面キャプチャ」の続きというか改良版というか
この間の記事ではwebView2のキャプチャを同期的に待って画像を取得していたのですが
今回は別スレッドで非同期実行して結果をイベント通知でもらう形に書き直しました。
マルチスレッド的になるので若干速くなるとかCPU資源を有効に活用できるという点ではいいかと思います。
ソースはこんな感じ
このプログラムを実行する前にVB.netのプロジェクトにWebView2をインストールしておいて
フォームにWebView2コントロール、ボタン、ピクチャーボックスを一個ずつ配置してください
呼び出し元のフォーム画面
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' WebView2コントロール初期化
InitializeAsync()
End Sub
Private Async Sub InitializeAsync()
Await WebView2.EnsureCoreWebView2Async(Nothing)
' URLを開く
WebView2.CoreWebView2.Navigate("https://www.yahoo.co.jp/")
End Sub
' ClassWebView2_Captクラスをイベントを受け取る形で定義
WithEvents classWebView2_Capt As New ClassWebView2_Capt
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' webCapture開始
classWebView2_Capt.webCapture(WebView2)
End Sub
' classWebView2_Captでイメージが生成された際に呼ばれるイベント
Private Sub dispWebImage(img As Image) Handles classWebView2_Capt.retImage
Me.PictureBox1.Image = img
End Sub
End Class
webView2コントロールのキャプチャ用クラス
Public Class ClassWebView2_Capt
' イメージが生成されたときに発火するイベント
Event retImage(img As Image)
' WebView2コントロールのイメージを取得する
Public Async Sub webCapture(WebView2 As Microsoft.Web.WebView2.WinForms.WebView2)
' イメージが格納されるメモリーストリーム
Dim ms As New System.IO.MemoryStream()
' WebView2のキャプチャ(非同期実行)
Await WebView2.CoreWebView2.CapturePreviewAsync(Microsoft.Web.WebView2.Core.CoreWebView2CapturePreviewImageFormat.Png, ms)
''非同期実行タスクを待つ
Await Task.Run(
Sub()
' メモリーストリームに書き込み完了するまで待つ
Do While ms.Length = 0
System.Threading.Thread.Sleep(100)
Loop
' メモリーストリームに書き込み完了したら得られたイメージをretImageイベントで返す
RaiseEvent retImage(Image.FromStream(ms))
End Sub
)
End Sub
End Class
やっていること自体は前回とあまり変わっていませんがWebView2側のイベントが終わるまで待つのにDoeventsで処理させるのではなく
別のスレッドで実行させることにより、WebView2のイベントをそちら側で勝手に処理するようになったことくらいです。
あとWebView2.CapturePreviewAsyncの終了の判定方法を変えました。
メモリーストリームにデータが書き込まれた時点でイメージが取得できたという判定方法に変えています。
イメージが取得できた場合に retImage イベントをRaiseEventしてイベントの受け取り
Form1のdispWebImage関数で結果のイメージを受け取っています。
かなり大きなイメージをキャプチャしても(9000x9000pxとか)体感的にあまり変わらないので
同期処理でも非同期でもどっちでもいい気はするのですが
昨今のマルチコアのCPUで効率的に処理をするにはこちらの方が良いのではないかと…
要はマルチスレッド版を書いてみたかっただけなのね。