原文:
背水一战 Windows 10 (62) - 控件(媒体类): InkCanvas 保存和加载, 手写识别
背水一战 Windows 10 (62) - 控件(媒体类): InkCanvas 保存和加载, 手写识别
作者:webabcd
介绍
背水一战 Windows 10 之 控件(媒体类)
- InkCanvas 保存和加载
- InkCanvas 手写识别
示例
1、演示 InkCanvas 涂鸦板的保存和加载
Controls/MediaControl/InkCanvasDemo3.xaml
<Page x:Class="Windows10.Controls.MediaControl.InkCanvasDemo3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.MediaControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <Border Background="White" Width="480" Height="320" Margin="5" HorizontalAlignment="Left"> <!-- InkCanvas - 涂鸦板控件 --> <InkCanvas Name="inkCanvas" /> </Border> <Button Name="save" Content="保存到文件" Margin="5" Click="save_Click" /> <Button Name="load" Content="从文件读取" Margin="5" Click="load_Click" /> </StackPanel> </Grid> </Page>
Controls/MediaControl/InkCanvasDemo3.xaml.cs
/* * InkCanvas - 涂鸦板控件(继承自 FrameworkElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/) * InkPresenter - 获取 InkPresenter 对象 * * InkPresenter - 涂鸦板 * StrokeContainer - 返回 InkStrokeContainer 类型的对象 * * InkStrokeContainer - 用于管理涂鸦 * IAsyncOperationWithProgress<UInt32, UInt32> SaveAsync(IOutputStream outputStream) - 保存涂鸦数据 * IAsyncActionWithProgress<UInt64> LoadAsync(IInputStream inputStream) - 加载涂鸦数据 */ using System; using System.Collections.Generic; using Windows.Foundation; using Windows.Storage; using Windows.Storage.Pickers; using Windows.Storage.Streams; using Windows.UI; using Windows.UI.Core; using Windows.UI.Input.Inking; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace Windows10.Controls.MediaControl { public sealed partial class InkCanvasDemo3 : Page { public InkCanvasDemo3() { this.InitializeComponent(); inkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch; InkDrawingAttributes drawingAttributes = inkCanvas.InkPresenter.CopyDefaultDrawingAttributes(); drawingAttributes.IgnorePressure = true; drawingAttributes.Color = Colors.Red; drawingAttributes.Size = new Size(4, 4); inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes); } private async void save_Click(object sender, RoutedEventArgs e) { if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Count == 0) return; // 用于保存涂鸦数据 IRandomAccessStream stream = new InMemoryRandomAccessStream(); await inkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream); // 文件保存对话框 var picker = new FileSavePicker { SuggestedStartLocation = PickerLocationId.DocumentsLibrary }; picker.FileTypeChoices.Add("ink files", new List<string>() { ".ink" }); // 弹出文件保存对话框 var file = await picker.PickSaveFileAsync(); if (file == null) return; // 在调用 CompleteUpdatesAsync 之前,阻止对文件的更新 CachedFileManager.DeferUpdates(file); // Stream 转 byte[] DataReader reader = new DataReader(stream.GetInputStreamAt(0)); await reader.LoadAsync((uint)stream.Size); byte[] bytes = new byte[stream.Size]; reader.ReadBytes(bytes); // 写入文件 await FileIO.WriteBytesAsync(file, bytes); // 保存文件 await CachedFileManager.CompleteUpdatesAsync(file); } private async void load_Click(object sender, RoutedEventArgs e) { // 文件打开对话框 var picker = new FileOpenPicker { SuggestedStartLocation = PickerLocationId.DocumentsLibrary }; picker.FileTypeFilter.Add(".ink"); // 弹出文件打开对话框 var pickedFile = await picker.PickSingleFileAsync(); if (pickedFile != null) { // 读取涂鸦数据 IRandomAccessStreamWithContentType stream = await pickedFile.OpenReadAsync(); // 加载指定的涂鸦数据 await inkCanvas.InkPresenter.StrokeContainer.LoadAsync(stream); } } } }
2、演示 InkCanvas 涂鸦板的手写识别
Controls/MediaControl/InkCanvasDemo4.xaml
<Page x:Class="Windows10.Controls.MediaControl.InkCanvasDemo4" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.MediaControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <Border Background="White" Width="480" Height="320" Margin="5" HorizontalAlignment="Left"> <!-- InkCanvas - 涂鸦板控件 --> <InkCanvas Name="inkCanvas" /> </Border> <Button Name="recognize" Content="手写识别" Margin="5" Click="recognize_Click" /> <TextBlock Name="lblMsg" Margin="5" /> </StackPanel> </Grid> </Page>
Controls/MediaControl/InkCanvasDemo4.xaml.cs
/* * InkCanvas - 涂鸦板控件(继承自 FrameworkElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/) * InkPresenter - 获取 InkPresenter 对象 * * InkRecognizerContainer - 用于管理手写识别 * GetRecognizers() - 获取 InkRecognizer 对象集合 * SetDefaultRecognizer(InkRecognizer recognizer) - 将指定的 InkRecognizer 设置为默认的手写识别器 * RecognizeAsync(InkStrokeContainer strokeCollection, InkRecognitionTarget recognitionTarget) - 识别,返回 InkRecognitionResult 对象集合 * InkStrokeContainer strokeCollection - 需要识别的 InkStrokeContainer 对象 * InkRecognitionTarget recognitionTarget - 需要识别的目标 * All - 识别全部涂鸦数据 * Selected - 识别被选中的涂鸦数据 * Recent - 识别 InkStroke 的 Recognized 为 false 的涂鸦数据 * * InkRecognizer - 手写识别器 * Name - 手写识别器的名字(只读) * * InkRecognitionResult - 手写识别结果 * BoundingRect - 获取用于识别的涂鸦的 Rect 区域 * GetStrokes() - 获取用于识别的 InkStroke 对象集合 * GetTextCandidates() - 获取识别结果,这是一个候选结果列表 * * InkPresenter - 涂鸦板 * StrokeContainer - 返回 InkStrokeContainer 类型的对象 * * InkStrokeContainer - 用于管理涂鸦 * UpdateRecognitionResults(IReadOnlyList<InkRecognitionResult> recognitionResults) - 将指定的识别结果通知给 InkStrokeContainer(此时 InkStrokeContainer 中被识别的 InkStroke 的 Recognized 将被标记为 true) * 如果使用的是 InkRecognitionTarget.All 则 InkStrokeContainer 中的所有的 InkStroke 的 Recognized 将被标记为 true * 如果使用的是 InkRecognitionTarget.Selected 则 InkStrokeContainer 中的被选中的 InkStroke 的 Recognized 将被标记为 true * GetRecognitionResults() - 返回之前通过 UpdateRecognitionResults 方法设置的数据 * * InkStroke - 涂鸦对象(这是一次的涂鸦对象,即鼠标按下后移动然后再抬起后所绘制出的涂鸦) * Recognized - 此 InkStroke 是否被识别了 * Selected - 此 InkStroke 是否被选中了 */ using System; using System.Collections.Generic; using System.Diagnostics; using Windows.Foundation; using Windows.UI; using Windows.UI.Core; using Windows.UI.Input.Inking; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace Windows10.Controls.MediaControl { public sealed partial class InkCanvasDemo4 : Page { public InkCanvasDemo4() { this.InitializeComponent(); inkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch; InkDrawingAttributes drawingAttributes = inkCanvas.InkPresenter.CopyDefaultDrawingAttributes(); drawingAttributes.IgnorePressure = true; drawingAttributes.Color = Colors.Red; drawingAttributes.Size = new Size(4, 4); inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes); } private async void recognize_Click(object sender, RoutedEventArgs e) { if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Count == 0) return; InkRecognizerContainer container = new InkRecognizerContainer(); lblMsg.Text = "手写识别器: "; lblMsg.Text += Environment.NewLine; // 获取当前支持的手写识别器列表,如果有多个的话可以通过 SetDefaultRecognizer 方法来指定默认的手写识别器 IReadOnlyList<InkRecognizer> recognizers = container.GetRecognizers(); foreach (InkRecognizer ir in recognizers) { lblMsg.Text += ir.Name; lblMsg.Text += Environment.NewLine; } lblMsg.Text += Environment.NewLine; lblMsg.Text += "识别结果: "; lblMsg.Text += Environment.NewLine; IReadOnlyList<InkRecognitionResult> result = await container.RecognizeAsync(inkCanvas.InkPresenter.StrokeContainer, InkRecognitionTarget.All); foreach (string textCandidate in result[0].GetTextCandidates()) { lblMsg.Text += textCandidate; lblMsg.Text += Environment.NewLine; } // 将识别结果通知给 InkStrokeContainer inkCanvas.InkPresenter.StrokeContainer.UpdateRecognitionResults(result); // 识别结果通知给 InkStrokeContainer 后,被识别的 InkStroke 的 Recognized 将被标记为 true // 如果在识别的时候使用的是 InkRecognitionTarget.All 则所有的 InkStroke 的 Recognized 将被标记为 true // 如果在识别的时候使用的是 InkRecognitionTarget.Selected 则被选中的 InkStroke 的 Recognized 将被标记为 true IReadOnlyList<InkStroke> strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes(); foreach (InkStroke stroke in strokes) { Debug.WriteLine("stroke.Recognized: " + stroke.Recognized); } // 这个获取到的就是之前通过 InkStrokeContainer 方式设置的数据 result = inkCanvas.InkPresenter.StrokeContainer.GetRecognitionResults(); } } }
OK
[源码下载]