2018-11-2-win10-uwp-通过-win2d-画出笔迹
| title | author | date | CreateTime | categories | 
|---|---|---|---|---|
| win10 uwp 通过 win2d 画出笔迹 | lindexi | 2018-11-2 20:11:0 +0800 | 2018-11-02 16:18:47 +0800 | UWP win2d | 
本文告诉大家如何在 UWP 上让 win2d 画出笔迹,通过实际测试发现在 UWP 的笔迹的性能比在 WPF 高很多。但是如果只是使用默认的 InkCanvas 可以做的很少,同时性能也不是特别高,在加上 win2d 才可以做到和来画一样快的性能
在参加微软技术暨生态大会 2018听了邵猛大佬的利用 Windows 新特性开发出更好的手绘视频应用学到了使用 win2d 可以画出笔迹。
在之前我一直在想来画的笔迹性能为什么那么好,现在终于了解到了,于是本文就将具体实现写出来。本文的代码不可以用在实际项目上,因为假设用户都是正常书写
在 UWP 的笔迹有设置对笔迹完全控制,在中文翻译,会将 Ink 翻译为墨迹,本文将 Ink 翻译为笔迹或墨迹。
界面
如果想要在 win2d 画出笔迹,还是需要使用 InkCanvas 来收集笔迹,不能直接通过 Pointer 来做。通过测试使用 Pointer 和 InkCanvas 的性能相差在我的设备是 16 ms 左右,需要知道,笔迹的书写过程,相差 16 ms 是一个很大的值。
至于为什么通过 InkCanvas 收集笔迹需要在本文下方告诉大家 InkCanvas 的原理。
因为使用 win2d 需要通过 Nuget 安装,这部分请看在项目安装win2d 本文就直接使用
先引用命名空间 xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml" 这样就可以在界面通过 canvas 使用高性能的 win2d 来画笔迹
<canvas:CanvasControl x:Name="Canvas"/>
<InkCanvas x:Name="InkCanvas"/>
笔迹性能原理
为什么通过 InkCanvas 可以拿到很高的性能?
因为在 InkCanvas 使用了不清真的方式实现了从触摸收集点的方法,而使用 Pointer 是通过消息循环给到程序,同时 Pointer 还需要经过路由事件,这样就让笔迹书写速度不够快。如果 InkCanvas 只是更快收到触摸消息,那么也无法做到像现在这么快的速度。尝试写一个空白的 UWP 程序,在里面添加笔迹控件,在移动的过程中,进入断点,这时你还可以继续在 UWP 应用上画。
也就是 InkCanvas 的书写和 UWP 的主线程是分开的
在 UWP 的笔迹渲染是分为三个过程,第一个过程是跟随,也就是将当前的点和上一个点直接连出一条线。第二个过程是动态笔迹层,在书写过程就是进行动态笔迹渲染,这时将使用最快的方式画出笔迹。第三个过程是静态笔迹,在 UWP 官方是 Drying 将动态笔迹成为湿笔迹,就像使用钢笔写的一样。而从湿到干就是动态转静态的笔迹。将笔迹转为静态就可以让笔迹变为一个界面元素,参与界面的变化,如选择和层级这些业务。
在动态笔迹只是做渲染,用最快的算法从触摸收集到的点画出来,而静态笔迹就是将动态笔迹转换为普通的元素,可以用来做业务
当然大家也不会关注为什么笔迹在 UWP 那么快,于是就继续在后台代码添加设置。我才不告诉大家,我也不知道他是怎么做的
完全控制墨迹
在 UWP 的笔迹可以通过调用 ActivateCustomDrying 方法完全控制笔迹的静态渲染,也就是 InkCanvas 可以让代码处理从动态转静态的方法
_inkSynchronizer = InkCanvas.InkPresenter.ActivateCustomDrying();
这里需要使用字段 _inkSynchronizer 记录笔迹
多指输入
原来的 InkCanvas 不支持多指输入,通过下面的代码可以让 InkCanvas 支持多笔
InkCanvas.InkPresenter.SetPredefinedConfiguration(InkPresenterPredefinedConfiguration
.SimpleMultiplePointer);
转换笔迹
转换笔迹的时候需要在 win2d 上画出静态笔迹
Canvas.Draw += CanvasControl_Draw
在这个函数里面可以通过 win2d 画出任意的内容
但是需要知道在什么时候开始画,同时 win2d 需要调用 Invalidate 刷新,在笔迹的一笔画完之后可以通过 InkPresenter_StrokesCollected 事件拿到添加的笔迹
            InkCanvas.InkPresenter.StrokesCollected += InkPresenter_StrokesCollected;
        private void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
        {
        }
在 InkPresenter_StrokesCollected 就可以将笔迹从动态转换为静态在 Win2d 添加用户的元素
通过 _inkSynchronizer.BeginDry() 拿到现在的所有动态的笔迹
从函数上可以看到有 BeginDry 应该就有 EndDry 尝试两个函数一起调用,会发现调用了 EndDry 之后动态笔迹就消失了。如果这时还没有将静态笔迹画出来,界面就看不到原来的笔迹
在 UWP 可以多次调用 BeginDry 拿到动态笔迹,假如现在有动态笔迹 1、2 调用 BeginDry 会返回动态笔迹 1、2 然后用户继续触摸,在界面有动态笔迹 3 再次调用BeginDry会返回第三条笔迹。
但是只能调用一次 EndDry 也就是在调用多次 BeginDry 只有只能调用一次 EndDry 不能相邻两次调用 EndDry 方法
在 win2d 画静态笔迹首先需要刷新界面
private void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
{
_pendingDry = inkSynchronizer.BeginDry(); Canvas.Invalidate();
}
在 Canvas 的刷新函数画出笔迹
using (CanvasDrawingSession ds = sender.CreateDrawingSession())
{
ds.DrawInk(_pendingDry);
}
无限漫游
如果现有做无限漫游,可以使用 CanvasVirtualControl 做一个超级大的画布,同时只画出可见的范围
这样可以做到无限漫游添加很多笔迹而软件不会变卡
2018-11-2-win10-uwp-通过-win2d-画出笔迹的更多相关文章
- win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑
		本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ... 
- win2d 画出好看的图形
		本文告诉大家,win2d 不需要从零开始做,以前做出来的很多库其实只需要做很小修改就可以做出好看的效果,而且用在 UWP 上.本文修改原先 大神写的 GDI 图形到 win2d 上,而且可以运行起来 ... 
- win2d 通过 CanvasActiveLayer 画出透明度和裁剪
		本文告诉大家如果在 UWP 的 win2d 通过 CanvasActiveLayer 创建一层,在这里画出的图片有透明度或者裁剪 在 win2d 如果需要对某个元素裁剪,可以使用很多方法,本文只是告诉 ... 
- win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl
		本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件. 在之前的入门教程win10 uwp win2d 入门 看这一篇就够了我直接用的是CanvasControl,实际上 ... 
- win10 uwp 渲染原理 DirectComposition 渲染
		本文来告诉大家一个新的技术DirectComposition,在 win7 之后(实际上是 vista),微软正在考虑一个新的渲染机制 在 Windows Vista 就引入了一个服务,桌面窗口管理器 ... 
- win10 uwp 萤火虫效果
		原文:win10 uwp 萤火虫效果 本文在Nukepayload2指导下,使用他的思想用C#写出来. 本文告诉大家,如何使用 win2d 做出萤火虫效果. 安装 win2d 安装win2d的方法请使 ... 
- win10 uwp 使用 Microsoft.Graph 发送邮件
		在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ... 
- win10 uwp 毛玻璃
		毛玻璃在UWP很简单,不会和WPF那样伤性能. 本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃. 毛玻璃可以使用 win2D 方法,也可以使用 Compositor . 使用 win2d 得 ... 
- OI生涯回忆录 2018.11.12~2019.4.15
		上一篇:OI生涯回忆录 2017.9.10~2018.11.11 一次逆风而行的成功,是什么都无法代替的 ………… 历经艰难 我还在走着 一 NOIP之后,全机房开始了省选知识的自学. 动态DP,LC ... 
- win10 uwp 使用 Matrix3DProjection 进行 3d 投影
		原文:win10 uwp 使用 Matrix3DProjection 进行 3d 投影 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 ... 
随机推荐
- Leetcode700.Search in a Binary Search Tree二叉搜索树中的搜索
			给定二叉搜索树(BST)的根节点和一个值. 你需要在BST中找到节点值等于给定值的节点. 返回以该节点为根的子树. 如果节点不存在,则返回 NULL. class Solution { public: ... 
- Gradle中的buildScript,gradle wrapper,dependencies等一些基础知识
			就想收藏一篇好文,哈哈,无他 Gradle中的buildScript代码块 - 黄博文 然后记录一些gradle的基础知识: 1.gradle wrapper就是对gradle的封装,可以理解为项目内 ... 
- PHP开发api接口安全验证的实例,值得一看
			php的api接口 在实际工作中,使用PHP写api接口是经常做的,PHP写好接口后,前台就可以通过链接获取接口提供的数据,而返回的数据一般分为两种情况,xml和json,在这个过程中,服务器并不知道 ... 
- SPSS能做Cochran-Armitage趋势检验吗
			SPSS能做Cochran-Armitage趋势检验吗 Cochran-Armitage (CA) 趋势检验是一种用于分析1个二分类变量和1个有序分类变量关联性的统计方法,由Cochran和Armti ... 
- python中的输入和输出
			输入和输出 输出: 用print()在括号中加上字符串,就可以向屏幕上输出指定的文字.比如输出'hello, world',用代码实现如下: >>> print('hello, ... 
- k8s 超详细总结,面试必问
			一个目标:容器操作:两地三中心:四层服务发现:五种Pod共享资源:六个CNI常用插件:七层负载均衡:八种隔离维度:九个网络模型原则:十类IP地址:百级产品线:千级物理机:万级容器:相如无亿,K8s有亿 ... 
- 将Gradle项目发布到Maven Central库中
			本文主要介绍如何一个由gradle构建的项目部署到Maven Central. 网上大部分都是介绍如何将由maven构建的项目部署到Maven Central.与Gradle相关的比较少. 申请账号 ... 
- Python学习之路7☞装饰器
			一:命名空间与作用域 1.1命名空间 局部命名空间: def foo(): x=1 def func(): pass 全局命名空间: import time class ClassName:pass ... 
- phpexcel导出数据库成excel文件
			<?php error_reporting(E_ALL); date_default_timezone_set('Europe/London'); /** PHPExcel */ require ... 
- linux下安装使用MySQL 以及 python mysqldb 遇到的问题
			一.安装mysql sudo apt-get install mysql-client-core-5.5 然后会出现: ERROR 2002 (HY000): Can't connect to loc ... 
