通用 Windows InkCanvas 笔划在 RenderTargetBitmap.RenderAsync 上消失
Universal Windows InkCanvas strokes disappear on RenderTargetBitmap.RenderAsync
我尝试在 windows 10 通用应用程序中将 InkCanvas 的笔触渲染到 RenderTargetBitmap。这是我的 xaml 代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="10" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="container">
<Rectangle Fill="LightBlue" />
<InkCanvas x:Name="InkCanvas" />
</Grid>
<Image Grid.Row="2" x:Name="TheImage" />
<Button Grid.Row="3" Content="CopyToRendertargt" Click="Button_Click" />
</Grid>
这是我设置 Image.Source 属性:
的代码
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
InkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
RenderTargetBitmap renderTarget = new RenderTargetBitmap();
await renderTarget.RenderAsync(this.container);
this.TheImage.Source = renderTarget;
}
}
当我单击按钮时,我在 InkCanvas 上所做的笔划消失并且 InkCanvas 被冻结,直到我调整应用程序 window。笔画未渲染到 RenderTargetBitmap。图像仅显示浅蓝色矩形。
有人对此有解决方案吗?
** 更新**
对于那些正在寻找将笔画保存到 uwp 位图的正确方法的人。我找到了将 InkCanvas Strokes 保存到位图的 UWP 方式: InkStrokeContainer 对象有一个名为 SaveAsync(...) 的方法可以保存笔画流。如果您将此流用作位图的源,您将获得作为位图的笔划。
InkStrokeContainer container = TheInkCanvas.InkPresenter.StrokeContainer;
WriteableBitmap bmp;
using (InMemoryRandomAccessStream ims =
new InMemoryRandomAccessStream())
{
await container.SaveAsync(ims);
bmp = await new WriteableBitmap(1, 1)
.FromStream(ims, BitmapPixelFormat.Bgra8);
}
*注:本示例代码中使用了WriteableBitmapEx(https://www.nuget.org/packages/WriteableBitmapEx/)
在XAMLvisuals和RenderTargetBitmap部分RenderTargetBitmap documentation中描述:无法捕获的内容在捕获的图像中显示为空白,但其他内容在同一视觉中tree 仍然可以被捕获并呈现(存在无法捕获的内容不会使 XAML 合成的整个捕获无效)。因此 InkCanvas 的内容可能是不可捕获的。
另一种方法是使用 Win2D(Microsoft 的 Direct2D .NET 包装器)。 Win2D 可以通过 nuget 包在 UWP 应用程序中使用。您将能够管理墨迹笔划并将它们保存为图像(jpeg、png 和其他格式)。
您可以使用 Win2D 渲染墨迹。
- 从 NuGet
添加 Win2D.uwp 到项目
- 将此 InkCanvasExtensions.cs 文件添加到您的项目中
- 更改命名空间或将
using Zoetrope;
添加到您的来源
- 创建图像文件或流并将其传递给 InkCanvas.RenderAsync()
InkCanvasExtensions.cs
namespace Zoetrope
{
using System;
using System.Threading.Tasks;
using Microsoft.Graphics.Canvas;
using Windows.Graphics.Display;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Xaml.Controls;
/// <summary>
/// InkCanvas Extensions
/// </summary>
public static class InkCanvasExtensions
{
/// <summary>
/// Render an InkCanvas to a stream
/// </summary>
/// <param name="inkCanvas">the ink canvas</param>
/// <param name="fileStream">the file stream</param>
/// <param name="backgroundColor">the background color</param>
/// <param name="fileFormat">the file format</param>
/// <returns>an async task</returns>
public static async Task RenderAsync(
this InkCanvas inkCanvas,
IRandomAccessStream fileStream,
Color backgroundColor,
CanvasBitmapFileFormat fileFormat)
{
// do not put in using{} structure - it will close the shared device.
var device = CanvasDevice.GetSharedDevice();
var width = (float) inkCanvas.ActualWidth;
var height = (float) inkCanvas.ActualHeight;
var currentDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
using (var offscreen = new CanvasRenderTarget(device, width, height, currentDpi))
{
using (var session = offscreen.CreateDrawingSession())
{
session.Clear(backgroundColor);
session.DrawInk(inkCanvas.InkPresenter.StrokeContainer.GetStrokes());
}
await offscreen.SaveAsync(fileStream, fileFormat);
}
}
}
}
我尝试在 windows 10 通用应用程序中将 InkCanvas 的笔触渲染到 RenderTargetBitmap。这是我的 xaml 代码:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="10" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="container">
<Rectangle Fill="LightBlue" />
<InkCanvas x:Name="InkCanvas" />
</Grid>
<Image Grid.Row="2" x:Name="TheImage" />
<Button Grid.Row="3" Content="CopyToRendertargt" Click="Button_Click" />
</Grid>
这是我设置 Image.Source 属性:
的代码public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
InkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
RenderTargetBitmap renderTarget = new RenderTargetBitmap();
await renderTarget.RenderAsync(this.container);
this.TheImage.Source = renderTarget;
}
}
当我单击按钮时,我在 InkCanvas 上所做的笔划消失并且 InkCanvas 被冻结,直到我调整应用程序 window。笔画未渲染到 RenderTargetBitmap。图像仅显示浅蓝色矩形。
有人对此有解决方案吗?
** 更新**
对于那些正在寻找将笔画保存到 uwp 位图的正确方法的人。我找到了将 InkCanvas Strokes 保存到位图的 UWP 方式: InkStrokeContainer 对象有一个名为 SaveAsync(...) 的方法可以保存笔画流。如果您将此流用作位图的源,您将获得作为位图的笔划。
InkStrokeContainer container = TheInkCanvas.InkPresenter.StrokeContainer;
WriteableBitmap bmp;
using (InMemoryRandomAccessStream ims =
new InMemoryRandomAccessStream())
{
await container.SaveAsync(ims);
bmp = await new WriteableBitmap(1, 1)
.FromStream(ims, BitmapPixelFormat.Bgra8);
}
*注:本示例代码中使用了WriteableBitmapEx(https://www.nuget.org/packages/WriteableBitmapEx/)
在XAMLvisuals和RenderTargetBitmap部分RenderTargetBitmap documentation中描述:无法捕获的内容在捕获的图像中显示为空白,但其他内容在同一视觉中tree 仍然可以被捕获并呈现(存在无法捕获的内容不会使 XAML 合成的整个捕获无效)。因此 InkCanvas 的内容可能是不可捕获的。
另一种方法是使用 Win2D(Microsoft 的 Direct2D .NET 包装器)。 Win2D 可以通过 nuget 包在 UWP 应用程序中使用。您将能够管理墨迹笔划并将它们保存为图像(jpeg、png 和其他格式)。
您可以使用 Win2D 渲染墨迹。
- 从 NuGet 添加 Win2D.uwp 到项目
- 将此 InkCanvasExtensions.cs 文件添加到您的项目中
- 更改命名空间或将
using Zoetrope;
添加到您的来源 - 创建图像文件或流并将其传递给 InkCanvas.RenderAsync()
InkCanvasExtensions.cs
namespace Zoetrope
{
using System;
using System.Threading.Tasks;
using Microsoft.Graphics.Canvas;
using Windows.Graphics.Display;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Xaml.Controls;
/// <summary>
/// InkCanvas Extensions
/// </summary>
public static class InkCanvasExtensions
{
/// <summary>
/// Render an InkCanvas to a stream
/// </summary>
/// <param name="inkCanvas">the ink canvas</param>
/// <param name="fileStream">the file stream</param>
/// <param name="backgroundColor">the background color</param>
/// <param name="fileFormat">the file format</param>
/// <returns>an async task</returns>
public static async Task RenderAsync(
this InkCanvas inkCanvas,
IRandomAccessStream fileStream,
Color backgroundColor,
CanvasBitmapFileFormat fileFormat)
{
// do not put in using{} structure - it will close the shared device.
var device = CanvasDevice.GetSharedDevice();
var width = (float) inkCanvas.ActualWidth;
var height = (float) inkCanvas.ActualHeight;
var currentDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
using (var offscreen = new CanvasRenderTarget(device, width, height, currentDpi))
{
using (var session = offscreen.CreateDrawingSession())
{
session.Clear(backgroundColor);
session.DrawInk(inkCanvas.InkPresenter.StrokeContainer.GetStrokes());
}
await offscreen.SaveAsync(fileStream, fileFormat);
}
}
}
}