在UWP开发中,微软提供了一个新型的InkCanvas控件用来让用户能书写墨迹,在新版的Edga浏览器中微软自己也用到了该控件使用户很方便的可以在web上做笔记。
InkCanvas控件使用很简单,从工具箱里拖出一个InkCanvas控件即可,InkCanvas有个属性叫InkPresenter,通过它我们可以多样化的设置我们的画笔属性,InkPresenter里面有几个重要的属性:
1 // 获取或设置输入数据用于从中提取 InkStroke 的输入设备类型。 2 3 public CoreInputDeviceTypes InputDeviceTypes { get; set; } 4 5 6 // 获取 InkCanvas 控件上的 InkStroke 的行为。例如,墨迹、清除或选择。 7 8 public InkInputProcessingConfiguration InputProcessingConfiguration { get; } 9 10 11 // 获取或设置是否已启用输入以进行墨迹书写。 12 13 public System.Boolean IsInputEnabled { get; set; } 14 15 16 // 获取或设置 InkStrokeContainer 对象以管理 InkCanvas 控件上的一个或多个 InkStroke 对象的输入、处理和操作。 17 18 public InkStrokeContainer StrokeContainer { get; set; } 19 20 21 // 从关联的 InkCanvas 控件获取笔划墨迹输入。 22 23 public InkStrokeInput StrokeInput { get; } 24 25 26 // 设置 InkCanvas 控件上一个或多个接触点的墨迹书写行为。 27 28 public void SetPredefinedConfiguration(InkPresenterPredefinedConfiguration value); 29 30 31 // 指定渲染新的 InkStroke 时 InkCanvas 控件所使用的 InkDrawingAttributes。 32 33 public void UpdateDefaultDrawingAttributes(InkDrawingAttributes value);
接下来我们做一个画图板,功能要实现墨迹书写,墨迹擦除,墨迹保存,墨迹加载,手写识别。
墨迹书写
前台声明一个InkCanvas控件:
<InkCanvas x:Name="InkCanvas" />
后台设置下Ink的墨笔属性:
1 private void MainPage_Loaded(object sender, RoutedEventArgs e) 2 { 3 //设置输入类型为触控输入和鼠标输入 4 InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch; 5 //创建一个新的画笔属性(此步可省略,省略后采用默认画笔) 6 var attr = new InkDrawingAttributes 7 { 8 Color = Colors.Red, //颜色 9 IgnorePressure = true, //是否忽略数字化器表面上的接触压力 10 PenTip = PenTipShape.Rectangle, //笔尖类型设置 11 Size = new Size(4, 10), //画笔粗细 12 PenTipTransform = Matrix3x2.CreateRotation((float)(70 * Math.PI / 180)) //笔尖形状矩阵 13 }; 14 //更新画笔 15 InkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(attr); 16 }
墨迹擦除
墨迹擦除只需要设置画笔行为为橡皮擦即可
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Erasing;
墨迹保存
1 private async void Btn_Save_OnClick(object sender, RoutedEventArgs e) 2 { 3 //声明一个流来存储墨迹信息 4 IRandomAccessStream stream = new InMemoryRandomAccessStream(); 5 //保存墨迹信息到流 6 //拿到流了就可以随意处置墨迹了,可以保持到App内部 也可以保存为文件,我们直接保存为文件 7 await InkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream); 8 //创建一个文件保存对话框 9 var picker = new Windows.Storage.Pickers.FileSavePicker 10 { 11 SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary 12 }; 13 //文件类型 14 picker.FileTypeChoices.Add("INK files", new List<string>() { ".ink" }); 15 //弹出保存对话框 16 var file = await picker.PickSaveFileAsync(); 17 if (file == null) return; 18 19 CachedFileManager.DeferUpdates(file); 20 //将流转为byte 21 var bt = await ConvertImagetoByte(stream); 22 //写入文件 23 await Windows.Storage.FileIO.WriteBytesAsync(file, bt); 24 //保存 25 await CachedFileManager.CompleteUpdatesAsync(file); 26 } 27 private async Task<byte[]> ConvertImagetoByte(IRandomAccessStream fileStream) 28 { 29 //IRandomAccessStream fileStream = await image.OpenAsync(FileAccessMode.Read); 30 var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0)); 31 await reader.LoadAsync((uint)fileStream.Size); 32 33 byte[] pixels = new byte[fileStream.Size]; 34 35 reader.ReadBytes(pixels); 36 37 return pixels; 38 }
墨迹加载
1 private async void Btn_load_OnClick(object sender, RoutedEventArgs e) 2 { 3 //创建一个文件选择器 4 var picker = new Windows.Storage.Pickers.FileOpenPicker 5 { 6 SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary 7 }; 8 //规定文件类型 9 picker.FileTypeFilter.Add(".ink"); 10 //显示选择器 11 var pickedFile = await picker.PickSingleFileAsync(); 12 if (pickedFile != null) 13 { 14 var file = await pickedFile.OpenReadAsync(); 15 //加载墨迹 16 await InkCanvas.InkPresenter.StrokeContainer.LoadAsync(file); 17 } 18 }
手写识别
手写识别是指通过用户使用画笔写出的墨迹,我们可以识别出是什么内容,主要是通过InkRecognizerContainer类来完成的。
InkRecognizerContainer类有几个主要方法:
// 获取 InkRecognizer 对象的集合。 public IReadOnlyList<InkRecognizer> GetRecognizers(); // 对一个或多 InkStroke 对象执行手写识别。 public IAsyncOperation<IReadOnlyList<InkRecognitionResult>> RecognizeAsync(InkStrokeContainer strokeCollection, InkRecognitionTarget recognitionTarget); // 设置用于手写标识的默认 InkRecognizer。 public void SetDefaultRecognizer(InkRecognizer recognizer);
具体使用方法:
1 private async void btnOcr_OnClick(object sender, RoutedEventArgs e) 2 { 3 //手写识别 4 var container = new InkRecognizerContainer(); 5 //使用墨迹识别 6 var result = await container.RecognizeAsync(InkCanvas.InkPresenter.StrokeContainer, InkRecognitionTarget.All); 7 //获取识别结果 InkRecognitionResult 对象中还能获取候选字 8 var txt = result[0].GetTextCandidates()[0]; 9 10 var dia = new ContentDialog() 11 { 12 Content = new TextBlock() { Text = txt }, 13 PrimaryButtonText = "ok", 14 IsPrimaryButtonEnabled = true 15 16 }; 17 dia.PrimaryButtonClick += (s, a) => 18 { 19 dia.Hide(); 20 }; 21 await dia.ShowAsync(); 22 }
Ink Toolbar control
上面介绍了Ink控件的基本使用方法,其中最主要的就是画笔属性的设置,为了方便大家的开发,微软还提供了一个辅助Control叫做Ink Toolbar,通过它,我们可以很方便的集成一个画笔设置工具栏。
首先安装该工具扩展,然后引用InkToolbar Control.dll,接着在View中声明控件:
xmlns:ink="using:Microsoft.Labs.InkToolbarControl" <ink:InkToolbar x:Name="bar_InkTool" TargetInkCanvas="{x:Bind InkCanvas}" VerticalAlignment="Top" HorizontalAlignment="Right" />
TargetInkCanvas属性bind到要设置的InkCanvas上即可。
效果图:
推荐一个UWP开发群:53078485 大家可以进来一起学习