首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >开源项目Avalonia DotNetCampus.InkCanvas

开源项目Avalonia DotNetCampus.InkCanvas

作者头像
JusterZhu
发布2025-11-24 13:38:27
发布2025-11-24 13:38:27
1710
举报
文章被收录于专栏:JusterZhuJusterZhu

DotNetCampus.InkCanvas(书写笔迹画板) 起源于 Avalonia 社区的一个实际需求(AvaloniaUI/issues/1477),旨在为.NET 开发者提供一款开箱即用的笔迹画板控件。无论是简单的手写输入、绘图标注,还是复杂的笔迹交互场景,它都能轻松应对,帮助开发者快速实现笔迹相关功能。

作者:lindexi

仓库地址:https://github.com/dotnet-campus/DotNetCampus.InkCanvas

欢迎各位参与开源项目的建设,多多star!

Avalonia InkCanvas

快速开始

安装 NuGet 包 DotNetCampus.AvaloniaInkCanvas

代码语言:javascript
复制
  <ItemGroup>
    <PackageReference Include="DotNetCampus.AvaloniaInkCanvas" Version="1.0.0-alpha.2" />
  </ItemGroup>

在 XAML 中使用 InkCanvas 控件

代码语言:javascript
复制
xmlns:inking="using:DotNetCampus.Inking"

<inking:InkCanvas x:Name="InkCanvas"/>

在代码中使用 InkCanvas 控件,切换不同的输入模式

代码语言:javascript
复制
     // 切换书写模式
     InkCanvas.EditingMode = InkCanvasEditingMode.Ink;
     // 切换橡皮擦模式
     InkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;

FAQ

Q: 这个库支持 AOT 编译吗?

A: 支持。这个库经过测试,确认可以在 AOT 环境下正常工作。

Q: 这个库可以在 Linux 环境下使用吗?

A: 可以。这个库基于 Avalonia 和 SkiaSharp 构建,这些都是支持 Linux 的跨平台框架。

Q: 我是否能直接用这个库制作出一个高性能笔迹白板应用?

A: 不可以。受限于 Avalonia 的渲染性能,目前这个库还不能用来制作高性能的笔迹白板应用。如果你需要一个高性能的笔迹白板应用,建议在 Windows 平台上添加 WPF 加速层,使用 WPF 绘制笔迹以提升性能;在 Linux 平台上使用 X11 原生绘制以提升性能。相关讨论请参考 https://github.com/AvaloniaUI/Avalonia/discussions/18702

进阶用法

切换笔迹渲染器

当前内置了以下笔迹渲染器:

  • SimpleInkRender: 最简单的笔迹渲染器,适合大部分场景,速度快,逻辑简单。但在某些输入情况下,笔迹可能出现锯齿等问题
  • WpfForSkiaInkStrokeRenderer: 使用 WPF 的笔迹渲染算法的渲染器,适合对笔迹质量要求较高的场景,但性能相对较低。其实现代码源于 WPF 开源仓库,逻辑复杂

切换笔迹渲染器示例:

代码语言:javascript
复制
 AvaloniaSkiaInkCanvasSettings settings = InkCanvas.SkiaInkCanvas.Settings;
 // 使用 WPF 的笔迹渲染算法的渲染器
 settings.InkStrokeRenderer = new WpfForSkiaInkStrokeRenderer();
 // 使用默认简单的笔迹渲染器
 settings.InkStrokeRenderer = null;

注: 使用 WpfForSkiaInkStrokeRenderer 仅使用 WPF 开源仓库中的笔迹渲染算法代码,不依赖 WPF 框架本身

处理笔迹收集事件
代码语言:javascript
复制
        InkCanvas.StrokeCollected += (o, args) =>
        {
            var addedStroke = args.SkiaStroke;
        };
处理笔迹擦除事件
代码语言:javascript
复制
        InkCanvas.StrokeErased += (o, args) =>
        {
            foreach (ErasedSkiaStroke erasedSkiaStroke in args.ErasingSkiaStrokeList)
            {
                if (erasedSkiaStroke.IsErased)
                {
                    // 被擦掉的笔迹
                    IReadOnlyList<SkiaStroke> newStrokes = erasedSkiaStroke.NewStrokeList;

                    // 一段笔迹可以被擦掉成多段笔迹。但也可能被完全擦掉,变成 0 段笔迹
                    foreach (var skiaStroke in newStrokes)
                    {
                        
                    }
                }
                else
                {
                    // 没有被擦掉的笔迹,保持原样
                    SkiaStroke originalStroke = erasedSkiaStroke.OriginStroke;
                }
            }
        };
控制橡皮擦属性

通过 AvaloniaSkiaInkCanvasSettings 进行控制,例如:

代码语言:javascript
复制
        AvaloniaSkiaInkCanvasSettings settings = InkCanvas.SkiaInkCanvas.Settings;
        settings.EraserSize = new Size(100, 200);
如何自定义橡皮擦界面
  1. 编写一个继承自 Control 的橡皮擦控件,且让其实现 IEraserView 接口
  2. 将该橡皮擦控件的创建委托赋值给 InkCanvas.AvaloniaSkiaInkCanvas.Settings 的 EraserViewCreator 属性

示例代码如下:

代码语言:javascript
复制
internal class CustomEraserView : Control, IEraserView
{
    ...
}

        var settings = InkCanvas.AvaloniaSkiaInkCanvas.Settings;
        settings.EraserViewCreator = new DelegateEraserViewCreator(() => new CustomEraserView());

注: 不能在使用过程中动态更换 EraserViewCreator 属性,仅支持在初始化时设置该属性。应当在任何橡皮擦视图创建之前设置该属性

将笔迹导出为 SVG 图片

演示将每一笔笔迹导出为单独的 SVG 图片:

代码语言:javascript
复制
    private void SaveStrokeAsSvgButton_OnClick(object? sender, RoutedEventArgs e)
    {
        var saveFolder = Path.Join(AppContext.BaseDirectory, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}");
        Directory.CreateDirectory(saveFolder);

        using var skPaint = new SKPaint();
        skPaint.IsAntialias = true;
        skPaint.Style = SKPaintStyle.Fill;

        for (var i = 0; i < InkCanvas.Strokes.Count; i++)
        {
            var saveSvgFile = Path.Join(saveFolder, $"{i}.svg");
            using var fileStream = File.Create(saveSvgFile);

            var stroke = InkCanvas.Strokes[i];

            var bounds = InkCanvas.Bounds.ToSKRect();
            using var skCanvas = SKSvgCanvas.Create(bounds, fileStream);

            skPaint.Color = stroke.Color;
            skCanvas.DrawPath(stroke.Path, skPaint);
        }
    }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Avalonia InkCanvas
  • 快速开始
  • FAQ
  • 进阶用法
    • 切换笔迹渲染器
    • 处理笔迹收集事件
    • 处理笔迹擦除事件
    • 控制橡皮擦属性
    • 如何自定义橡皮擦界面
    • 将笔迹导出为 SVG 图片
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档