0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

webView2コントロールの画面キャプチャをしたくて(非同期版)

Last updated at Posted at 2021-10-28

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で効率的に処理をするにはこちらの方が良いのではないかと…
要はマルチスレッド版を書いてみたかっただけなのね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?