在做白板书写的时候,会有各种笔的绘制,比如 书写笔、马克笔、演示笔等等。粉笔的功能需求也是很有必要的。

上网搜了一圈,几乎没有绘制粉笔的。

有的是毛笔、楷体等绘制的如下博客:

wpf inkcanvas customink 毛笔效果_wpf inkcanvas 笔锋-CSDN博客

【WPF】 InkCanvas 书写毛笔效果-CSDN博客

绘制粉笔的思路,一开始是源于 github的一个仓库:mychalkboard/MyChalkBoard: MyChalkBoard is an application for you to quickly sketch with a chalk.

对应的网页的链接:MyChalkBoard

思路:就是用一个通用的笔头(ImageSource),利用Stroke 捕获到的StylusPoints的点,生成对应的点的坐标,调用drawingContext.DrawImage,绘制图案

1、生成笔头

找UI绘制一个粉笔形状的图片,以Png为例:

 2、支持修改颜色

参考了该博文: 2018-8-10-WPF-修改图片颜色-CSDN博客

只要是修改 WriteableBitmap 的RGBA的值,达到替换颜色的效果

 public static unsafe ImageSource ConvertImageColor(Color newColor, WriteableBitmap writableBitmap)
{
var bitmap = writableBitmap;
if (bitmap == null)
{
return null;
}
bitmap.Lock();
var length = bitmap.PixelWidth * bitmap.PixelHeight *
bitmap.Format.BitsPerPixel / 8;
var backBuffer = (byte*)bitmap.BackBuffer;
var byteList = new byte[length];
for (int i = 0; i + 4 < length; i = i + 4)
{
byteList[i] = newColor.B;
byteList[i + 1] = newColor.G;
byteList[i + 2] = newColor.R;
byteList[i + 3] = backBuffer[i + 3];
}
bitmap.Unlock();
bitmap = new WriteableBitmap(bitmap.PixelWidth, bitmap.PixelHeight, 96, 96,
bitmap.Format, bitmap.Palette);
bitmap.Lock();
bitmap.WritePixels(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight),
byteList, bitmap.BackBufferStride, 0);
bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
bitmap.Unlock();
return bitmap;
}

3、收集点迹

主要是调用了我们组内自研封装的一套基于鼠标、触摸汇总的笔迹点迹收集的算法(WPF 输入附加事件 - 唐宋元明清2188 - 博客园),通过 Down、Move、Up以及分段汇总的方式,收集并呈现笔迹

4、自定义补点

由于通过设备采集到的点,会有疏密的区分,所以对于比较稀疏的点,需要通过补点的方式,达到减少锯齿的效果,具体的补点的距离,因业务需要不同,可以通过调节参数的方式做适配

 //标识上一个点
var previousPoint = new Point(double.NegativeInfinity, double.NegativeInfinity);
for (int i = 0; i < stylusPoints.Count; i++)
{
var pressureFactor = stylusPoints[i].PressureFactor * 2;
var currentPoint = stylusPoints[i].ToPoint();
var vector = previousPoint - currentPoint;
var newWidth = width * pressureFactor;
//作为基准值
var baseWidth = newWidth / 1.5;
if (!double.IsInfinity(vector.Length) && vector.Length > baseWidth)
{
var w2 = newWidth;
if (newWidth - vector.Length > newWidth)
w2 = newWidth - vector.Length; var newPointCount = (int)(vector.Length / (baseWidth)) * 2;
var dx = (currentPoint.X - previousPoint.X) / newPointCount;
var dy = (currentPoint.Y - previousPoint.Y) / newPointCount; for (int pointCount = 0; pointCount < newPointCount; pointCount++)
{
var newX = previousPoint.X + dx * (pointCount + 1);
var newY = previousPoint.Y + dy * (pointCount + 1);
drawingContext.DrawImage(imageSource, new Rect(newX - w2, newY - w2, w2 * 2, w2 * 2));
}
}
else
{
Rect rectangle = new Rect(currentPoint.X - newWidth, currentPoint.Y - newWidth, newWidth * 2, newWidth * 2);
drawingContext.DrawImage(imageSource, rectangle);
}
previousPoint = currentPoint;

5、绘制点迹

通过以上4个前提步骤,就可以计算出来笔迹的大小,通过调用 drawingContext.DrawImage 的方式把带粉笔头的Image绘制出来

drawingContext.DrawImage(imageSource, new Rect(newX - w2, newY - w2, w2 * 2, w2 * 2));

6、效果如下:

普通书写

重力慢速书写(仿压着粉笔写字):

WPF 粉笔绘制的更多相关文章

  1. wpf 后台绘制圆弧

    wpf 前台绘制圆弧很简单,如:<Path x:Name="path_data" Stroke="#FFE23838" StrokeThickness=& ...

  2. C#WPF 如何绘制几何图形 图示教程 绘制sin曲线 正弦 绘制2D坐标系 有图有代码

    原文:C#WPF 如何绘制几何图形 图示教程 绘制sin曲线 正弦 绘制2D坐标系 有图有代码 C#WPF 如何绘制几何图形? 怎么绘制坐标系?绘制sin曲线(正弦曲线)? 这离不开Path(Syst ...

  3. WPF 图形绘制 及各种线帽、箭头的实现

    原文:WPF 图形绘制 及各种线帽.箭头的实现  /// <summary>     /// 矩形类     /// </summary>     public sealed ...

  4. WPF特效-绘制实时2D激光雷达图

    原文:WPF特效-绘制实时2D激光雷达图 接前两篇: https://blog.csdn.net/u013224722/article/details/80738619 https://blog.cs ...

  5. 【C#】第3章补充(一)如何在WPF中绘制正弦曲线

    分类:C#.VS2015 创建日期:2016-06-19 使用教材:(十二五国家级规划教材)<C#程序设计及应用教程>(第3版) 一.要点 本例子提前使用了教材第13章介绍的基本知识. 二 ...

  6. 在WPF中绘制多维数据集

    原文 https://stuff.seans.com/2008/08/13/drawing-a-cube-in-wpf/ 是时候使用WPF绘制一个简单的3D对象了.作为WPF中3D图形的快速介绍,让我 ...

  7. WPF 如何绘制不规则按钮,并且有效点击范围也是不规则的

    最近在做一个东西,如地图,点击地图上的某一区域,这一区域需要填充成其他颜色.区域是不规则的,而且点击该区域的任一点,都能够变色.普通的按钮只是简单的加载一幅图肯定是不行的.查了很多资料,终于把它搞定了 ...

  8. WPF拖动绘制

    using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using ...

  9. wpf GeometryDrawing 绘制文字

    <GeometryDrawing x:Key="GeometryDrawingText"> <GeometryDrawing.Geometry> <R ...

  10. WPF绘制折线

    WPF后台绘制折线,填充到一个GRID下 private void btnPreview_Click(object sender, RoutedEventArgs e) { GridImg.Child ...

随机推荐

  1. 错误模块名称:vrfcore.dll

    记录一下. 应用程序莫名报这个错,其它电脑上正常. 可能是Application Verifier这个工具影响到了. 进入注册表:win+R->regedit->HKEY_LOCAL_MA ...

  2. 基于ThreeJs的大屏3D地图(二)——气泡图、渐变柱体与热力图

    前提 上一篇文章中我们完成了地图区块模型的渲染,在此基础之上本篇来讲解气泡图.3D柱形图以及3D热力图的实现方式. 首先,为了更好的关注点分离及与地图渲染模块的解耦,我们可以把所有类型的可视化元素抽象 ...

  3. mySql跳过行数获取多少行

    LIMIT :需要获取多少条记录 OFFSET :跳过前面的多少行记录从后面开始获取 SELECT * FROM USER LIMIT 32 OFFSET 1 只获取12行记录 跳过第一条记录 SEL ...

  4. 报错:ReferenceError: __dirname is not defined in ES module scope

    报错: __dirname is not defined in ES module scope 前言 新版 NodeJS 支持通过 ESM 方式导入模块,代码如: // CommonJS 规范(旧) ...

  5. ant-design-pro 自定义表单 rules规则

    表单输入 <ProFormText name="id" label={intl.formatMessage({ id: 'pages.secret.form.id' })} ...

  6. mac地址查询

    打开命令提示符窗口(cmd程序) 快捷键 win+r 打开运行窗口,输入 cmd 命令打开 命令提示符窗口 或者点击开始菜单,在搜索程序和文件输入框,输入 cmd(会找到进入dos命令的cmd程序) ...

  7. go 遍历修改切片数据

    package main import "fmt" type good struct { id int64 sum int64 } func main() { good1 := g ...

  8. Xshell连接VMware虚拟机中的CentOS

    步骤: 1. 检查Linux虚拟机的网络连接模式,确保它是NAT模式.(由于只在本机进行连接,所以没有选择桥接模式.当然,桥接模式的配置会有所不同,在此不做深入分析) 2. 在VMware works ...

  9. 编写你的第一个 Django 应用程序,第6部分

    本教程从教程 5 停止的地方开始.我们已经构建了一个经过测试的网络投票应用程序,现在我们将添加一个样式表和一个图像. 除了服务器生成的 HTML 之外,Web 应用程序通常需要提供呈现完整网页所需的其 ...

  10. .NET Core奇技淫巧之WinForm使用Python.NET并打包

    前言 之前整了一个GZY.EFCoreCompare 的库,可以用做对比实体与数据库结构.感兴趣可以去看看,地址:GZY.EFCoreCompare 但是只能导出execl表格. 后来大佬用Pytho ...