MicrosoftEdge / MicrosoftEdge/WebView2Feedback

WinUI RenderAsync method doesn't work for making screenshots of WebView2

Open
#2,799 3 comments 1 reaction 1 assignee View on GitHub

@champnic is already working on this.

Since Sep 16, 2022.

bug tracked
Dominant language
PowerShell
Stars
526
Forks
67
PR merge metrics
No merged PRs in 30d

Description

Description

In WinUI you can call RenderTargetBitmap.RenderAsync(element) to render a screenshot of an element to a bitmap, and then you can save that bitmap somewhere (for example, as a PNG on disk).

When there's a WebView2 in the control tree, the contents of the WebView2 are completely blank, though everything else in the image looks fine.

Version
SDK: Windows App SDK 1.1.5
Runtime: 105.0.1343.33
Framework: WinUI
OS: Win11

Repro Steps

Create a new empty WinUI3 app and put this code in MainWindow.xaml.cs:

    public sealed partial class MainWindow : Window
    {
        WebView2 _wv;
        public MainWindow()
        {
            var b = new Button { Content = new TextBlock { Text = "Do screenshot" } };
            b.Click += OnScreenshotClick;

            _wv = new WebView2 { Source = new Uri("https://bing.com"), Height=400, Width=400 };

            var sp = new StackPanel() { Orientation = Orientation.Vertical };
            sp.Children.Add(b);
            sp.Children.Add(_wv);
            Content = sp;
        }

        private async void OnScreenshotClick(object sender, RoutedEventArgs e)
        {
            var rootPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            await CaptureAsync(Content, Path.Combine(rootPath, "WindowContent.png"));
            await CaptureAsync(_wv, Path.Combine(rootPath, "WebView.png"));

            var messageDialog = new MessageDialog($"Screenshots saved to: {rootPath}");
            messageDialog.Commands.Add(new UICommand("OK"));
            InitializeWithWindow.Initialize(messageDialog, WindowNative.GetWindowHandle(this));
            await messageDialog.ShowAsync();
        }

        public static async Task CaptureAsync(UIElement element, string destination)
        {
            var bmp = new RenderTargetBitmap();

            await bmp.RenderAsync(element);

            // get the view information first
            var width = bmp.PixelWidth;
            var height = bmp.PixelHeight;

            // then potentially move to a different thread
            var pixels = await bmp.GetPixelsAsync();

            using FileStream fileStream = new FileStream(destination, FileMode.Create);

            var ms = fileStream.AsRandomAccessStream();

            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, ms);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)width, (uint)height, 96, 96, pixels.ToArray());
            await encoder.FlushAsync();
        }
    }

And then run the app, and click the button in the app.

On my machine it produces two screenshots:

  1. Just the WebView2 (blank rectangle):
    WebView
  2. The whole app's main window's contents, which has content, except for the blank WebView2 (valid screenshot, except bottom right is blank gray rectangle):
    WindowContent

Originally reported in .NET MAUI: https://github.com/dotnet/maui/issues/9718

AB#41360109

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.