1

I am using RenderTargetBitmap to capture the content of a control in XAML. I am aware of using Visibility="Collapse" that would hide the control, but when the control is collapsed then RenderTargetBitmap renders a blank image, because according to the docs

Content that's in the tree but with its Visibility set to Collapsed won't be captured.

and

Content that can't be captured will appear as blank in the captured image, but other content in the same visual tree can still be captured and will render (the presence of content that can't be captured won't invalidate the entire capture of that XAML composition).

However I don't want to display it on the screen.

I was looking for something like a z-index or a layer, so I don't display it but still be able to capture that element.

Alternatively some other way that does not use RenderTargetBitmap that renders the element even though the visibility is set to collapse

1
  • Did you ever find an appropriate solution for this? I have a very similar issue. Commented Feb 7, 2019 at 15:27

1 Answer 1

0

You can use the Grid as it stacks the elements. If you place an element at first it will be visually stacked below the second one only if they are in same row or column. In the sample below RedGrid is visualy below the WhiteGrid. So, you cannot visualy see it. But when you use RenderTargetBitmap for RedGrid it will return red colored rectangle as image

<Grid >
    <Grid.RowDefinitions>
       <RowDefinition/>
       <RowDefinition/>
    </Grid.RowDefinitions>
        <Grid x:Name="RedGrid" Background="Red" Height="100" Width="100"></Grid>
        <Grid x:Name="WhiteGrid" Background="White" Height="100" Width="100"></Grid>
        <Button Grid.Row="1" Content="Render" Click="Button_Click"></Button>
</Grid>

//C# code

 private async void Button_Click(object sender, RoutedEventArgs e)
        {
            RenderTargetBitmap rtb = new RenderTargetBitmap();
            await rtb.RenderAsync(GridToBeRendered);

            var pixelBuffer = await rtb.GetPixelsAsync();
            var pixels = pixelBuffer.ToArray();
            var displayInformation = DisplayInformation.GetForCurrentView();
            StorageFolder myfolder = ApplicationData.Current.LocalFolder;
            StorageFile file;
            file = await myfolder.CreateFileAsync("Render" + ".png", CreationCollisionOption.GenerateUniqueName);
            if (file != null)
            {
                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
                    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                         BitmapAlphaMode.Premultiplied,
                                         (uint)rtb.PixelWidth,
                                         (uint)rtb.PixelHeight,
                                         displayInformation.RawDpiX,
                                         displayInformation.RawDpiY,
                                         pixels);
                    await encoder.FlushAsync();
                }
            }
            await Launcher.LaunchFileAsync(file);
        }
1
  • I know that. This is what I am actually doing for the moment. I have another control on top of it. However I want to have the element I want to capture a large size. I don't want to stretch the control that is on top, and don't want the window or scrollview to be larger to accommodate a large background.
    – kkica
    Commented Dec 14, 2018 at 11:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.