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-画出笔迹的更多相关文章

  1. win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑

    本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...

  2. win2d 画出好看的图形

    本文告诉大家,win2d 不需要从零开始做,以前做出来的很多库其实只需要做很小修改就可以做出好看的效果,而且用在 UWP 上.本文修改原先 大神写的 GDI 图形到 win2d 上,而且可以运行起来 ...

  3. win2d 通过 CanvasActiveLayer 画出透明度和裁剪

    本文告诉大家如果在 UWP 的 win2d 通过 CanvasActiveLayer 创建一层,在这里画出的图片有透明度或者裁剪 在 win2d 如果需要对某个元素裁剪,可以使用很多方法,本文只是告诉 ...

  4. win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl

    本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件. 在之前的入门教程win10 uwp win2d 入门 看这一篇就够了我直接用的是CanvasControl,实际上 ...

  5. win10 uwp 渲染原理 DirectComposition 渲染

    本文来告诉大家一个新的技术DirectComposition,在 win7 之后(实际上是 vista),微软正在考虑一个新的渲染机制 在 Windows Vista 就引入了一个服务,桌面窗口管理器 ...

  6. win10 uwp 萤火虫效果

    原文:win10 uwp 萤火虫效果 本文在Nukepayload2指导下,使用他的思想用C#写出来. 本文告诉大家,如何使用 win2d 做出萤火虫效果. 安装 win2d 安装win2d的方法请使 ...

  7. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  8. win10 uwp 毛玻璃

    毛玻璃在UWP很简单,不会和WPF那样伤性能. 本文告诉大家,如何在 UWP 使用 win2d 做毛玻璃. 毛玻璃可以使用 win2D 方法,也可以使用 Compositor . 使用 win2d 得 ...

  9. OI生涯回忆录 2018.11.12~2019.4.15

    上一篇:OI生涯回忆录 2017.9.10~2018.11.11 一次逆风而行的成功,是什么都无法代替的 ………… 历经艰难 我还在走着 一 NOIP之后,全机房开始了省选知识的自学. 动态DP,LC ...

  10. win10 uwp 使用 Matrix3DProjection 进行 3d 投影

    原文:win10 uwp 使用 Matrix3DProjection 进行 3d 投影 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 ...

随机推荐

  1. laravel 图片上传 intervention/image

    1. composer require intervention/image 2). 修改 app/config/app.php 添加 ServiceProvider: // 将下面代码添加到 pro ...

  2. DTcms iis6 伪静态 iis配置方法 【图解】

    1.右键点击 要设置网站的网站 2.属性 ——>主目录 ——>配置——> 3.如右侧窗口,找到 .aspx 扩展名——>编辑——>复制 可执行文件的路径——>关闭 ...

  3. JFinalConfig

    概述 基于JFinal的web项目需要创建一个继承自JFinalConfig类的子类,该类用于对整个web项目进行配置. JFinalConfig子类需要实现六个抽象方法,如下所示: public c ...

  4. scroll 滚动到指定位置触发事件 and 点击一按钮/链接让页面定位在指定的位置

    scroll 滚动到指定位置触发事件:$(function(){ $(window).scroll(function() { var s =$(window).scrollTop(); if (s&g ...

  5. 接口测试 Postman 做接口自动化测试_入门篇

    可能是目前最好用的web接口调试工具 无需注册(注册后可多终端同步用例) 免费(每年付费$60可用云服务,30天免费试用) 保存历史记录 支持录制请求 基于Chrome的V8引擎,支持JS脚本(基本支 ...

  6. jQuery打飞机游戏

    在线演示 本地下载

  7. 显示调用dll

    原dll中导出的接口如图: Head.h: struct zint_render_line { float x, y, length, width; struct zint_render_line * ...

  8. Auto reloading enabled

    在eclipse中集成tomcat来开发时, 如果使用run as模式启动项目的话,tomcat配置Auto reloading enabled,我们修改java文件,项目会重新加载,修改的内容会生效 ...

  9. Liferay OSGi注解(Annotation) - 使用手册(译文)

    mark过来好好用 上Neil的博客地址Liferay OSGi注解(Annotation) - 使用手册(译文) @Component是注入服务 @Reference是获取服务(在Liferay框架 ...

  10. RDS 5.7三节点企业版时代的数据一致性解决方案

    上篇我们看到了在MySQL主备模式下,我们在数据一致性上做了不少事情,但解决方案都有一定的局限性,适合部分场景或者解决不彻底的问题.随着以Google Spanner以及Amazon Aruora 为 ...