2

I have a WPF application that screen captures all its open windows. One of my WPF windows has an embedded WPF WebBrowser control. For some reason, my code works fine for all the windows except those that have the web browser control. For these, my code generates blank images.

Here is the method (below) that generates the image. It seems that the call to RenderTargetBitmap works except for WebBrowser controls. Should it be a different call for windows having a web browser control?

    private byte[] GetJpgImage(List<UIElement> sources, int quality)
    {
        var sourceBrushItems = new List<SourceBrushItem>();
        double renderHeight = 0;
        double renderWidth = 0;
        double maximumHeight = 0;

        foreach (var source in sources)
        {
            var actualHeight = source.RenderSize.Height;
            var actualWidth = source.RenderSize.Width;

            if (actualHeight > maximumHeight)
            {
                renderHeight = actualHeight;
                maximumHeight = actualHeight;
            }
            
            renderWidth = renderWidth + actualWidth;
            
            var sourceBrush = new VisualBrush(source);
            sourceBrushItems.Add(new SourceBrushItem()
            {
                SourceBrush = sourceBrush,
                ActualHeight = actualHeight,
                ActualWidth = actualWidth
            });
        }
        var renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);

        var drawingVisual = new DrawingVisual();

        using (var drawingContext = drawingVisual.RenderOpen())
        {
            double x = 0;
            drawingContext.PushTransform(new ScaleTransform(1, 1));
            foreach (var sourceBrush in sourceBrushItems)
            {
                // Align images from left to right.
                drawingContext.DrawRectangle(sourceBrush.SourceBrush, null, new Rect(x, 0, sourceBrush.ActualWidth, sourceBrush.ActualHeight));
                x = x + sourceBrush.ActualWidth;
            }
        }

        renderTarget.Render(drawingVisual);

        var jpgEncoder = new JpegBitmapEncoder();
        jpgEncoder.QualityLevel = quality;
        jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

        Byte[] imageArray;

        using (var outputStream = new MemoryStream())
        {
            jpgEncoder.Save(outputStream);
            imageArray = outputStream.ToArray();
        }

        return imageArray;
    }

I searched many months for a solution for this but cannot seem to find a solution, as I learned that the WebBrowser control is not a real WPF element, or something that has to do with the airspace issue. I thought this was resolved in .NET 4.7.2 but it still does not work.

Can someone lead me to some direction on how I can screen capture this type of window?

Ray
  • 4,679
  • 10
  • 46
  • 92
  • 1
    Indeed, the actual `WebBrowser` rendering surface is not part of the visual tree so `RenderTargetBitmap` won't help. You could try a full desktop capture like this - https://stackoverflow.com/questions/1777033/desktop-screenshot-in-wpf - and then crop to the known boundaries of your main Window. I don't want to post this as an answer without trying it out but I'd be curious if that works for you. – Emperor Eto Jan 30 '23 at 22:57
  • Or if dumping `WebBrowser` is an option, you could try the much better Chromium Embedded Framework, which will (I'm 99% sure) work with `RenderTargetBitmap`. https://cefsharp.github.io/ – Emperor Eto Jan 30 '23 at 23:09
  • As Peter said, the display interface of the webbrowser is different from other controls, so you cannot use the rendertargetbitmap to take a screenshot. – Jiale Xue - MSFT Jan 31 '23 at 03:53
  • Or maybe this approach https://stackoverflow.com/questions/3884966/save-screenshot-of-wpf-web-browser-frame – Andy Jan 31 '23 at 08:42

0 Answers0