利用微软的Ink,实现手写输入。
不用自带的InkCanvas,重写的绘制的效果。
根据速度调节线条粗细了。其实不算是线条吧,PathGeometry对象。
然后再向Ink引擎传入笔画数据,其实就是点。上两张图

字写的不好看。来看看代码吧

主要代码:

Imports Microsoft.Ink
'Imports System.Windows.Ink'C:\Program Files (x86)\Common Files\Microsoft Shared\Ink
'添加对 WPF 墨迹分析程序集、IAWinFX.dll、IACore.dll 和 IALoader.dll(这些内容可以在 \Program Files\Reference Assemblies\Microsoft\Tablet PC\v1.7 中找到)的引用。Structure PointInfoPublic pt As Point REM 点的位置Public dir As Vector REM 与上一个点之间的方向Public len As Single REM 上一个点到这个点的距离Public perpendicular As Vector REM 与上一个点之间的方向的垂直Public Function ToDrawingPoint() As System.Drawing.PointReturn New System.Drawing.Point(pt.X, pt.Y)End Function
End StructureClass MainWindowPrivate bmp As RenderTargetBitmap REM 渲染到的图片Private dv As New DrawingVisual() REM 绘制到图片的visualPrivate geo As PathGeometry REM 一笔 存的所有的pathPrivate geos As New List(Of PathGeometry) REM 所有笔划Private ptStart As Point REM 起始点Private ptEnd As Point REM 终点Private ptinfos As New List(Of PointInfo) REM 点的信息REM 求垂直与输入向量的向量,顺时针,应该还有更好的写法吧Public Function Perpendicular(v As Vector) As VectorDim result As VectorIf v.Y = 0 And v.X = 1 ThenReturn New Vector(0, -1)ElseIf v.Y = 0 And v.X = -1Return New Vector(0, 1)ElseIf v.Y > 0 Thenresult.X = Math.Sqrt(v.Y * v.Y / (v.X * v.X + v.Y * v.Y))Elseresult.X = -Math.Sqrt(v.Y * v.Y / (v.X * v.X + v.Y * v.Y))End IfEnd Ifresult.Y = -v.X * result.X / v.YReturn resultEnd Function REM 顺时针Private Sub canvas_MouseUp(sender As Object, e As MouseButtonEventArgs)ptEnd = e.MouseDevice.GetPosition(canvas)Dim g As New PathGeometry()Dim infoPrev As PointInfo = ptinfos.Last()Dim ptPrev As Point = infoPrev.ptDim len As SingleDim pt1, pt2 As PointDim dir0 As Vectordir0 = infoPrev.dirpt1 = ptPrev + dir0 * lw * -0.5 / infoPrev.lenpt2 = ptPrev + dir0 * lw * 0.5 / infoPrev.lenDim pf As New PathFigure()pf.Segments.Add(New LineSegment(ptPrev, True))pf.Segments.Add(New LineSegment(pt1, True))pf.Segments.Add(New LineSegment(ptEnd, True))pf.Segments.Add(New LineSegment(pt2, True))pf.StartPoint = ptPrevpf.IsClosed = Trueg.Figures.Add(pf)geo.AddGeometry(g)geos.Add(geo)Dim drawing As New GeometryDrawing(Brushes.Transparent, New Pen(Brushes.Black, 1), g)Dim dc As DrawingContext = dv.RenderOpen()dc.DrawDrawing(drawing)dc.Close()bmp.Render(dv)Dim info As PointInfoinfo.pt = ptEndinfo.len = leninfo.dir = New Vector()info.perpendicular = New Vector()tiwp.Clear()tiwp.Add(Regconize()) REM 添加识别到的文字到控件ptinfos.Clear()End SubPrivate lw As Single = 5.0Private Sub Canvas_MouseMove(sender As Object, e As MouseEventArgs)Dim pt As Point = e.GetPosition(canvas)Dim dir As Vector = New Vector()Dim len As Single = 0.0Dim vdir As Vector = New Vector()Dim g As New PathGeometry()If e.LeftButton = MouseButtonState.Pressed ThenDim dc As DrawingContext = dv.RenderOpen()If ptinfos.Count = 1 ThenDim pt1, pt2 As Pointlen = Math.Sqrt((pt.X - ptStart.X) * (pt.X - ptStart.X) + (pt.Y - ptStart.Y) * (pt.Y - ptStart.Y))dir = ptStart - ptdir.Normalize()vdir = Perpendicular(dir)'dir1 = New Vector(0, 0) - dir0pt1 = pt + vdir * lw * 0.5 / lenpt2 = pt + vdir * lw * -0.5 / lenDim pf As New PathFigure()pf.Segments.Add(New LineSegment(ptStart, True))pf.Segments.Add(New LineSegment(pt1, True))pf.Segments.Add(New LineSegment(pt2, True))pf.StartPoint = ptStartpf.IsClosed = Trueg.Figures.Add(pf)geo.AddGeometry(g)ElseDim infoPrev As PointInfo = ptinfos.Last()Dim ptPrev As Point = infoPrev.ptDim pt1, pt2, pt3, pt4 As Pointlen = Math.Sqrt((pt.X - ptPrev.X) * (pt.X - ptPrev.X) + (pt.Y - ptPrev.Y) * (pt.Y - ptPrev.Y))dir = ptPrev - ptdir.Normalize()Dim dir0 As Vector = infoPrev.perpendicularvdir = Perpendicular(dir)pt1 = ptPrev + dir0 * lw * 0.5 / infoPrev.lenpt2 = ptPrev + dir0 * lw * -0.5 / infoPrev.lenpt3 = pt + vdir * lw * 0.5 / lenpt4 = pt + vdir * lw * -0.5 / lenDim pf As New PathFigure()pf.Segments.Add(New LineSegment(ptPrev, True))pf.Segments.Add(New LineSegment(pt1, True))pf.Segments.Add(New LineSegment(pt3, True))pf.Segments.Add(New LineSegment(pt4, True))pf.Segments.Add(New LineSegment(pt2, True))pf.StartPoint = ptPrevpf.IsClosed = Trueg.Figures.Add(pf)geo.AddGeometry(g)End IfDim drawing As New GeometryDrawing(Brushes.Transparent, New Pen(Brushes.Black, 1), g)dc.DrawDrawing(drawing)dc.Close()bmp.Render(dv)Dim info As PointInfoinfo.pt = ptinfo.dir = dirinfo.len = leninfo.perpendicular = vdirptinfos.Add(info)End IfEnd SubPrivate Sub canvas_MouseDown(sender As Object, e As MouseButtonEventArgs)ptinfos.Clear()geo = New PathGeometry()ptStart = e.MouseDevice.GetPosition(canvas)Dim info As PointInfoinfo.pt = ptStartinfo.dir = New Vector()info.perpendicular = New Vector()info.len = 0ptinfos.Add(info)End SubPrivate Sub Window_Loaded(sender As Object, e As RoutedEventArgs)Me.InitializeComponent()bmp = New RenderTargetBitmap(512, 512, 96.0, 96.0, PixelFormats.Pbgra32)Dim brush As ImageBrush = New ImageBrush(bmp)brush.Stretch = Stretch.Fillcanvas.Background = brushInitRecognizer()End SubPrivate myRecognizers As Recognizers REM 所有识别器Private ink As New Microsoft.Ink.Ink() REM 墨迹Private strokes As Strokes REM 所有的笔画Private recognizectx As RecognizerContext REM 识别器上下文'Private myInkCollector As InkCollectorREM 初始化墨迹识别器Public Sub InitRecognizer()myRecognizers = New Recognizers()strokes = ink.CreateStrokes()recognizectx = myRecognizers.GetDefaultRecognizer().CreateRecognizerContext()recognizectx.Strokes = strokes'Dim helper As New Interop.WindowInteropHelper(Me)'Dim hwndsrc As Interop.HwndSource = PresentationSource.FromVisual(canvas)'myInkCollector = New InkCollector(hwndsrc.Handle)'myInkCollector.Enabled = TrueEnd SubPrivate Function Regconize() As String() REM 识别 ptinfos 中的点Dim listpts As New List(Of System.Drawing.Point)For Each i In ptinfoslistpts.Add(i.ToDrawingPoint())NextREM 每一笔转换成strokeDim stroke As Stroke = ink.CreateStroke(listpts.ToArray())REM 添加到识别器的上下文recognizectx.Strokes.Add(stroke)Dim recognizestatus As New RecognitionStatus()Dim recognizeresult As RecognitionResult = recognizectx.Recognize(recognizestatus)REM 识别器的所有选择Dim recognizealternates As RecognitionAlternates = recognizeresult.GetAlternatesFromSelection()REM 列出识别器所识别出的内容Dim result As New List(Of String)For i = 0 To recognizealternates.Count - 1Dim text As String = recognizealternates.Item(i).ToString()'Console.WriteLine(text)result.Add(text)NextReturn result.ToArray()End FunctionPrivate Sub buttonClear_Click(sender As Object, e As RoutedEventArgs) Handles buttonClear.Clickgeos.Clear() REM 清除所有的笔划ptinfos.Clear() REM 清除一笔中所有点CreateNewBitmap()strokes.Clear() REM 清除所有的画笔tiwp.Clear() REM 清除控件中的选择End SubPrivate Sub buttonUndo_Click(sender As Object, e As RoutedEventArgs) Handles buttonUndo.Clickptinfos.Clear() REM 清除一笔中所有点CreateNewBitmap()If (geos.Count > 0) Then REM 笔划大于0strokes.RemoveAt(strokes.Count - 1) REM 清除上一笔geos.RemoveAt(geos.Count - 1) REM 清除上一笔Dim dc As DrawingContext = dv.RenderOpen()For Each g In geosDim drawing As New GeometryDrawing(Brushes.Black, New Pen(Brushes.Black, 1), g)dc.DrawDrawing(drawing)Nextdc.Close()bmp.Render(dv)End IfEnd SubPrivate Sub tiwp_ImageClick(sender As Object, e As EventArgs) Handles tiwp.ImageClickConsole.WriteLine(sender)geos.Clear() REM 清除所有的笔划ptinfos.Clear() REM 清除一笔中所有点CreateNewBitmap()strokes.Clear() REM 清除所有的笔划tiwp.Clear() REM 清除控件中的选择End SubPublic Sub CreateNewBitmap()bmp = New RenderTargetBitmap(512, 512, 96.0, 96.0, PixelFormats.Pbgra32)Dim brush As ImageBrush = New ImageBrush(bmp)brush.Stretch = Stretch.Fillcanvas.Background = brushEnd Sub
End Class

完整代码这里

点击打开链接

感谢支持。

WPF 使用Microsoft.Ink 做的墨迹输入法相关推荐

  1. 【C#/WPF】用Thumb做可拖拽的UI控件

    [C#/WPF]用Thumb做可拖拽的UI控件 原文:[C#/WPF]用Thumb做可拖拽的UI控件 需求:简单的可拖拽的图片 使用System.Windows.Controls.Primitives ...

  2. 【一】C# 基于WPF 使用CefSharp来做万能爬虫

    目录 [一]C# 基于WPF 使用CefSharp来做万能爬虫 [二]C# 基于WPF 使用CefSharp来做万能爬虫 [三]C# 基于WPF 使用CefSharp来做万能爬虫 [四]C# 基于WP ...

  3. WPF 使用 Composition API 做高性能渲染

    在 WPF 中很多小伙伴都会遇到渲染性能的问题,虽然 WPF 的渲染可以甩浏览器渲染几条街,但是还是支持不了游戏级的渲染.在 WPF 使用的 DX 只是优化等级为 9 和 DX 9 差不多的性能,微软 ...

  4. 红黑树做中文字符输入法

    前言 输入一个字符,匹配中文字符的输入法, 例如输入a,输出:啊阿,然后再输入n,即变成an,输出:鞍氨安俺按暗岸胺案, 要求要有搜索的接口,应该如何设计呢? 答案: 红黑树 步骤 1. 设计红黑树的 ...

  5. Microsoft.Ink namespace

    Reference to C:\Program Files\Reference Assemblies\Microsoft\Tablet PC\v1.7 转载于:https://www.cnblogs. ...

  6. 使用sql服务器发送贺卡_使用Microsoft Word做最后一分钟的节日贺卡

    使用sql服务器发送贺卡 So the presents are wrapped, but all of your family members are coming over in a few da ...

  7. Microsoft Surface--Bing™ Maps WPF Control

    最近Bing maps团队为我们带来了Bing™ Maps WPF Control ,现在是Beta 1版本,现在我们可以为Microsoft Surface提供地图开发. 新建项目 添加引用 Xam ...

  8. 2000条你应知的WPF小姿势 基础篇45-50 Visual TreeLogic Tree 附带两个小工具

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C#  和 2, ...

  9. [译]WPF 应用程序和MVVM设计模式 ——Josh Smith

    这篇文章讨论: 模式与WPF MVP模式 为什么MVVM更加适用于WPF 用MVVM构建一个应用程序 译文地址:         http://www.cnblogs.com/lujiao_cs/ar ...

最新文章

  1. bootstrap3中关于布局的两种样式
  2. docker删除image失败,conflict
  3. Hdu 3062. Party
  4. 谨记2017年8月30日10:03:26
  5. 必须进行支持的游戏方可使用此功能_C#8.0 新增功能
  6. 数据结构基础(17) --二叉查找树的设计与实现
  7. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)签到题E Evil Coordinate
  8. Windows Phone本地数据库(SQLCE):13、更新数据(翻译)
  9. 第四次作业随笔(计算器第二步)
  10. Xtrabackup--InnoDB备份工具介绍(1)
  11. PEP 8: E305 excepted 2 blank lines, after class or function definition, found 1
  12. 如何用计算机排版打表格,PPT怎么利用表格来进行排版
  13. 局部加权回归LOESS(locally weighted regression)
  14. Android 触摸事件机制(三) View中触摸事件详解
  15. 生成基于STM32f103zet6的宠物自动投食机的代码,实现定时、定量、自动的投食,并可以通过Tlink物联网平台控制投食机投喂食物和查看投食机的投喂状态...
  16. 如何快速定位接口响应慢问题
  17. uniapp和vue课程表实现、会议预约实现[表格table相同内容行的合并]
  18. 下载网页中的视频(m3u8文件下载,仅供交流学习)
  19. 【C语言】判断某年是否为闰年
  20. 对于Tencent Files文件夹需要来自LAPTOP-PH9TIHGE\用户名的权限才能删除的解决办法

热门文章

  1. 马上就要十一大长假了!还没订好机票?用Python写了一个钉钉订低价票脚本!
  2. VB打包时出现没有注册类,怎么解决,蟹蟹各位大神
  3. C#--color颜色对照表
  4. 车架识别手机端只是一种?
  5. 王道数据结构线性表:有读者认为直接去掉p结点会造成断链?
  6. 清华操作系统实验ucore_lab4
  7. 51驱动DS1302制作电子时钟1602显示
  8. 微信小程序获取地理位置信息
  9. YOLOv报错(Arial.ttf)
  10. 将vtt字幕转成srt