How do I save an image from CapturePreviewAsync stream?

I don't understand much about Async, but I get no errors when running this, and still I don't get an image in C:\temp\test.jpg - what am I doing wrong?

Private Sub WebView22_Click(sender As Object, e As EventArgs) Handles WebView22.Click
    grabpic()
End Sub

Public Async Function grabpic() As Threading.Tasks.Task
    Dim ms As System.IO.Stream
    Await (WebView22.CoreWebView2.CapturePreviewAsync(CoreWebView2CapturePreviewImageFormat.Jpeg, ms))
    Dim file As New System.IO.FileStream("C:\temp\test.jpg", IO.FileMode.Create)
    ms.CopyTo(file)
    ms.Close()
End Function

Solution 1:

There are a few problems with your code:

  1. You're not awaiting the graphics() function, and therefore exceptions are being silently swallowed. Also, I'm not exactly sure what triggers the Click event of a WebView2 control (assuming it can actually be triggered). So, instead, you probably should test using a button click, for example.

  2. You're not initializing ms at all, which will cause a NullReferenceException. You probably wanted to create an instance of MemoryStream.

  3. You're calling ms.CopyTo after writing to the stream. At that point, the current position will be at the end of the stream and nothing will be written to file. You either need to set the position at the beginning (i.e., ms.Seek(0, SeekOrigin.Begin) or use ms.WriteTo() instead.

With that, the graphics() method would look something like this:

Public Async Function grabpic() As Task
    Using ms As New IO.MemoryStream()
        Await WebView22.CoreWebView2.CapturePreviewAsync(
            CoreWebView2CapturePreviewImageFormat.Jpeg, ms)
        Using file As New IO.FileStream("C:\temp\test.jpg", IO.FileMode.Create)
            ms.Seek(0, IO.SeekOrigin.Begin)
            ms.CopyTo(file)
        End Using
    End Using
End Function

However, you don't really need a MemoryStream in this case. You could just write directly to the FileStream. Here's what the final code should look like:

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Await grabpic()
End Sub

Public Async Function grabpic() As Task
    Using file As New IO.FileStream("C:\temp\test.jpg", IO.FileMode.Create)
        Await WebView22.CoreWebView2.CapturePreviewAsync(
            CoreWebView2CapturePreviewImageFormat.Jpeg, file)
    End Using
End Function