Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WinRT C# how do I save an offscreen XAML tree using RenderTargetBitmap?

The following code throws a cryptic System.ArgumentException from the RenderAsync method "Value does not fall within the expected range." If on the other hand my Canvas is part of a visible XAML tree it works. Is it impossible to render some XAML that isn't displayed on screen?

Canvas c = new Canvas();
c.Width = 40;
c.Height = 40;
c.Background = new SolidColorBrush(Color.FromArgb(0xff, 0x80, 0xff, 0x80));

RenderTargetBitmap x = new RenderTargetBitmap();
await x.RenderAsync(c);

I almost thought this answer would work, but no luck, I guess it only applies to WPF: Create WPF element offscreen and render to bitmap

UPDATE:

So far my best idea is to put the Canvas I want to render to into the currently visible page but place it beneath what is normally the root UIElement that fills the screen so it isn't visible to the user:

<Grid>
    <Canvas x:Name="HiddenCanvas"/>
    <Grid x:Name="mainElement" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    </Grid>
</Grid>

It isn't beautiful but it seems to work. Lets see if anyone can do better

like image 876
satur9nine Avatar asked Aug 24 '13 14:08

satur9nine


People also ask

What is WinRT used for?

C++/WinRT is an entirely standard modern C++17 language projection for Windows Runtime (WinRT) APIs, implemented as a header-file-based library, and designed to provide you with first-class access to the modern Windows API.

What is C# WinRT?

C#/WinRT is a NuGet-packaged toolkit that provides Windows Runtime (WinRT) projection support for the C# language. A projection assembly is an interop assembly, which enables programming WinRT APIs in a natural and familiar way for the target language.

Is WinRT based on Win32?

Technology. WinRT is implemented in the programming language C++ and is object-oriented by design. Its underlying technology, the Windows API (Win32 API), is written mostly in the language C.

What is WinRT service?

WinRT allows developers to create safe "sandboxed" touchscreen applications available from the Microsoft Store. WinRT apps support both the x86 and ARM architectures and multiple programming languages, including C/C++, C#, Visual Basic and JavaScript. WinRT was augmented by the Universal Windows Platform (see UWP).


2 Answers

satur9nine's solution to put the rendered UI tree somewhere behind an opaque foreground seems to be the only supported solution. You could also fiddle with the opacity of the parent element to avoid having it showing up. Another option is to render it yourself with Direct2D or use something like the WinRTXamlToolkit.Composition.Render() methods from WinRT XAML Toolkit.

like image 60
Filip Skakun Avatar answered Oct 13 '22 01:10

Filip Skakun


WinRTXamlToolkit.Composition namespace has this extension that works. Just call this method:

await WriteableBitmapRenderExtensions.RenderToPngStream(element);
like image 35
user3471655 Avatar answered Oct 13 '22 01:10

user3471655