在UWP开发中,微软提供了一个新型的InkCanvas控件用来让用户能书写墨迹,在新版的Edga浏览器中微软自己也用到了该控件使用户很方便的可以在web上做笔记。

InkCanvas控件使用很简单,从工具箱里拖出一个InkCanvas控件即可,InkCanvas有个属性叫InkPresenter,通过它我们可以多样化的设置我们的画笔属性,InkPresenter里面有几个重要的属性:

 // 获取或设置输入数据用于从中提取 InkStroke 的输入设备类型。

 public CoreInputDeviceTypes InputDeviceTypes { get; set; }

 // 获取 InkCanvas 控件上的 InkStroke 的行为。例如,墨迹、清除或选择。

 public InkInputProcessingConfiguration InputProcessingConfiguration { get; }

 // 获取或设置是否已启用输入以进行墨迹书写。

 public System.Boolean IsInputEnabled { get; set; }

 // 获取或设置 InkStrokeContainer 对象以管理 InkCanvas 控件上的一个或多个 InkStroke 对象的输入、处理和操作。

 public InkStrokeContainer StrokeContainer { get; set; }

 // 从关联的 InkCanvas 控件获取笔划墨迹输入。

 public InkStrokeInput StrokeInput { get; }

 // 设置 InkCanvas 控件上一个或多个接触点的墨迹书写行为。

 public void SetPredefinedConfiguration(InkPresenterPredefinedConfiguration value);

 // 指定渲染新的 InkStroke 时 InkCanvas 控件所使用的 InkDrawingAttributes。

 public void UpdateDefaultDrawingAttributes(InkDrawingAttributes value);

接下来我们做一个画图板,功能要实现墨迹书写,墨迹擦除,墨迹保存,墨迹加载,手写识别。

墨迹书写

前台声明一个InkCanvas控件:

<InkCanvas x:Name="InkCanvas" />

后台设置下Ink的墨笔属性:

 private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
//设置输入类型为触控输入和鼠标输入
InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch;
//创建一个新的画笔属性(此步可省略,省略后采用默认画笔)
var attr = new InkDrawingAttributes
{
Color = Colors.Red, //颜色
IgnorePressure = true, //是否忽略数字化器表面上的接触压力
PenTip = PenTipShape.Rectangle, //笔尖类型设置
Size = new Size(, ), //画笔粗细
PenTipTransform = Matrix3x2.CreateRotation((float)( * Math.PI / )) //笔尖形状矩阵
};
//更新画笔
InkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(attr);
}

墨迹擦除

墨迹擦除只需要设置画笔行为为橡皮擦即可

    InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Erasing;

墨迹保存

 private async void Btn_Save_OnClick(object sender, RoutedEventArgs e)
{
//声明一个流来存储墨迹信息
IRandomAccessStream stream = new InMemoryRandomAccessStream();
//保存墨迹信息到流
//拿到流了就可以随意处置墨迹了,可以保持到App内部 也可以保存为文件,我们直接保存为文件
await InkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream);
//创建一个文件保存对话框
var picker = new Windows.Storage.Pickers.FileSavePicker
{
SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary
};
//文件类型
picker.FileTypeChoices.Add("INK files", new List<string>() { ".ink" });
//弹出保存对话框
var file = await picker.PickSaveFileAsync();
if (file == null) return; CachedFileManager.DeferUpdates(file);
//将流转为byte
var bt = await ConvertImagetoByte(stream);
//写入文件
await Windows.Storage.FileIO.WriteBytesAsync(file, bt);
//保存
await CachedFileManager.CompleteUpdatesAsync(file);
}
private async Task<byte[]> ConvertImagetoByte(IRandomAccessStream fileStream)
{
//IRandomAccessStream fileStream = await image.OpenAsync(FileAccessMode.Read);
var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt());
await reader.LoadAsync((uint)fileStream.Size); byte[] pixels = new byte[fileStream.Size]; reader.ReadBytes(pixels); return pixels;
}

墨迹加载

 private async void Btn_load_OnClick(object sender, RoutedEventArgs e)
{
//创建一个文件选择器
var picker = new Windows.Storage.Pickers.FileOpenPicker
{
SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary
};
//规定文件类型
picker.FileTypeFilter.Add(".ink");
//显示选择器
var pickedFile = await picker.PickSingleFileAsync();
if (pickedFile != null)
{
var file = await pickedFile.OpenReadAsync();
//加载墨迹
await InkCanvas.InkPresenter.StrokeContainer.LoadAsync(file);
}
}

手写识别

手写识别是指通过用户使用画笔写出的墨迹,我们可以识别出是什么内容,主要是通过InkRecognizerContainer类来完成的。

InkRecognizerContainer类有几个主要方法:

// 获取 InkRecognizer 对象的集合。
public IReadOnlyList<InkRecognizer> GetRecognizers(); // 对一个或多 InkStroke 对象执行手写识别。
public IAsyncOperation<IReadOnlyList<InkRecognitionResult>> RecognizeAsync(InkStrokeContainer strokeCollection, InkRecognitionTarget recognitionTarget); // 设置用于手写标识的默认 InkRecognizer。
public void SetDefaultRecognizer(InkRecognizer recognizer);

具体使用方法:

 private async void btnOcr_OnClick(object sender, RoutedEventArgs e)
{
//手写识别
var container = new InkRecognizerContainer();
//使用墨迹识别
var result = await container.RecognizeAsync(InkCanvas.InkPresenter.StrokeContainer, InkRecognitionTarget.All);
//获取识别结果 InkRecognitionResult 对象中还能获取候选字
var txt = result[].GetTextCandidates()[]; var dia = new ContentDialog()
{
Content = new TextBlock() { Text = txt },
PrimaryButtonText = "ok",
IsPrimaryButtonEnabled = true };
dia.PrimaryButtonClick += (s, a) =>
{
dia.Hide();
};
await dia.ShowAsync();
}

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 大家可以进来一起学习

Win10/UWP开发-Ink墨迹书写的更多相关文章

  1. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  2. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  3. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

  4. Win10 UWP开发实现Bing翻译

    微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...

  5. Win10/UWP开发—凭据保险箱PasswordVault

    PasswordVault用户凭据保险箱其实并不算是Win10的新功能,早在Windows 8.0时代就已经存在了,本文仅仅是介绍在UWP应用中如何使用凭据保险箱进行安全存储和检索用户凭据. 那么什么 ...

  6. Win10/UWP开发—使用Cortana语音指令与App的前台交互

    Win10开发中最具有系统特色的功能点绝对少不了集成Cortana语音指令,其实Cortana语音指令在以前的wp8/8.1时就已经存在了,发展到了Win10,Cortana最明显的进步就是开始支持调 ...

  7. Win10 UWP 开发系列:使用SQLite

    在App开发过程中,肯定需要有一些数据要存储在本地,简单的配置可以序列化后存成文件,比如LocalSettings的方式,或保存在独立存储中.但如果数据多的话,还是需要本地数据库的支持.在UWP开发中 ...

  8. Win10 UWP 开发系列:使用多语言工具包让应用支持多语言

    之前我在一篇blog中写过如何使用多语言工具包,见http://www.cnblogs.com/yanxiaodi/p/3800767.html 在WinEcos社区也发布过一篇详细的文章介绍多语言工 ...

  9. Win10/UWP开发—SystemNavigationManager

    Win10系统为确保所有应用中的一致导航体验,提供后退导航功能.当你的应用在手机.平板电脑上或者在支持系统后退功能的电脑或笔记本电脑上运行时,系统会在"后退"按钮被按下时通知你的应 ...

随机推荐

  1. 简化版c语言文法

    <程序> → <外部声明> | <程序的外部声明> <标识符类型> → <无类型> | <字符> | <整型> | ...

  2. 一眼看懂KMP匹配算法

    KMP算法——快速从字符串M(母串)中找出与字符串Z(子串)匹配的子串 例1: 0 1 2 3 4 5 M:a b c a b d Z:  a b d BF算法(最一般的算法,也叫“蛮力算法”): 将 ...

  3. 关于StatusStrip控件和StatusBar控件的小试

    今天,在网上查找资料,突然看到一个例子,但例子中提及的StatusBar控件,我发现在vs控件压根不存在,我就郁闷了,于是上网查找才知道,现在这个控件已经被StatusStrip控件给吞了,Statu ...

  4. Java 找不到主类错误

    Eclipse 运行java 程序,突然出现错误:没有或找不到主类. 在网上找了好多办法,都不行. jdk环境配置啊-->这个一般不会出错,因为以前都不会出现这种问题. 查看项目配置啥的--&g ...

  5. Android 设置ListView当前显示的item

    项目中可能会有这种需求:动态设置ListView显示的item 这种需求可能会出现在不同的情况下,有的是打开页面就要显示在特定的位置,也有的是浏览列表时实时更新数据并且改变了集合中数据,或者是某种条件 ...

  6. webView与OC的交互

    layout: post title: webView 的 iOS 与 js 交互 subtitle: iOS 与 js 交互的几种方式 author: manajay date: 2016-05-3 ...

  7. mysql语句中日期函数和日期的加减运算

    一.秒数和时钟格式的互相转化 SEC_TO_TIME(seconds) 返回seconds参数,变换成小时.分钟和秒,值以'HH:MM:SS'或HHMMSS格式化,取决于函数是在一个字符串还是在数字. ...

  8. lombok介绍

    Lombok是一种JavaArchive(JAR)文件,可用来消除Java代码的冗长.在写代码时,可以通过这个插件消除各种getter和setter,toString等常用方法. lombok 注解: ...

  9. android中添加背景音乐

    方法一:这是使用java中的多线程,另外new出一个类,用类来启动音乐. 这个方法,就像当初写java的小游戏一样,不过是在电脑上运行的,可以控制每一个动作,比如你的触碰动作,但是,在我这个游戏中,我 ...

  10. C#中IQueryable和IEnumberable的区别

    IQueryable和IEnumberable的区别主要在查询方面有区别 IQueryable查询时间是先把skip和Take翻译成sql语句,去数据库执行完成后把数据加载到内存中 IEnumbera ...