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 欢迎访问.如果当前博客图片看不到,请到 ...
随机推荐
- PHP基础-生成静态html页面原理是怎样
设置example.html为模板文件,然后按照此模板文件生成article-1.html~article-5.html,以此来做简单的演示,代码如下: <?php//将数据存入二维数组$con ...
- windows10 中微信(UWP)版本不显示通知消息
前言: 前段时间笔者更换了升级了WINDOWS10系统,从应用商店安装微信后,使用期间不会推送消息通知,右下角的通知栏也无法添加微信图标.搜索百度和Google后,发现很多人都是这样,这是微信(UWP ...
- HTML-DOM实例——实现带样式的表单验证
HTML样式 基于table标签来实现页面结构 <form id="form1"> <h2>增加管理员</h2> <table&g ...
- bzoj3522 Hotel
Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房(间).三个妹子住的房间要互不相同(否则要打起来了 ...
- 【JZOJ1611】Dining
题目描述 农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食.每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做 ...
- jQuery,javascript获得网页的高度和宽度$(document).height / $(window).height
一.javascript 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: documen ...
- Spring Security 的登录密码验证过程 UsernamePasswordAuthenticationFilter
认证过程如下 一.先判断请求(请求必须是post请求)地址是否为配置的 login-processing-url 值(默认/j_spring_security_check),如果不是,则放行,进入下一 ...
- java代码简单实现队列
1. 基于链表简单实现 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; / ...
- iOS之友盟错误统计解决
http://www.cocoachina.com/ios/20150720/12627.html http://lieyunye.github.io/blog/2013/09/10/how-to-a ...
- Python深入:Distutils安装包
一:简介 尽管Python标准库已经支持很多的功能,但是有时还是会需要以第三方模块的形式添加新的功能到Python中. 在最简单的场景中,是你要安装的模块,已经有了针对你的平台的安装版本,因此只需要像 ...