首页 > 其他分享 >WPF inkcavas 保存笔迹部分

WPF inkcavas 保存笔迹部分

时间:2023-09-07 11:23:52浏览次数:35  
标签:笔迹 selected some inkcavas Ink DrawingAttributes new WPF inkCanv

this.inkCanv.Strokes.Save(file);

And that's enough to save all the information needed to restore the Ink at a later time

Save Ink as a bitmap

Saving the Ink as a Bitmap is a little trickier, but not impossible. We simply use 3 nice objects RenderTargetBitmap,BmpBitmapEncoder and BitmapFrame in the manner shown below:

int marg = int.Parse(this.inkCanv.Margin.Left.ToString());
RenderTargetBitmap rtb = 
        new RenderTargetBitmap((int)this.inkCanv.ActualWidth - marg,
                (int)this.inkCanv.ActualHeight - marg, 0, 0, 
            PixelFormats.Default);
rtb.Render(this.inkCanv);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.Save(file);
file.Close();

It should come as no surprise that to load some Ink from a file its just the opposite of saving a file. As before we simply use a stream. In the attached app, I create a new file format called "Ink Serialized Format", but you can use whatever you like.

this.inkCanv.Strokes = new StrokeCollection(file);
In order to actually cut the Ink, you must Select some Ink to cut. This can be done in 2 ways, you may either use the Select button (this will be discussed here or the current stylus may be changed to be in select mode. This is also discussed in more detail here.

For now I'm going to assume that there is at least some Ink selected. You will be able to see the selected Ink as there will be a bounding rectangle with resize handles surrounding the Ink, as shown in the figure above. So once you've got some ink selected, you will be able to Cut it; it's very easy.

if (this.inkCanv.GetSelectedStrokes().Count > 0)
    this.inkCanv.CutSelection();

Copy Ink

Copying Ink is almost the same as Cutting it (Assuming you have some Ink selected), we simply use the CopySelection method of the InkCanvas instead of the CutSelection

if (this.inkCanv.GetSelectedStrokes().Count > 0)
    this.inkCanv.CopySelection();

Paste Ink

Pasting Ink is almost as easy (Assuming you have some Ink selected), let's have a look at that.

if (this.inkCanv.CanPaste())
    this.inkCanv.Paste();

Delete Ink

Deleting Ink is also very simple (Assuming you have some Ink selected), just check that there are some Strokes to remove, and remove them.

if (this.inkCanv.GetSelectedStrokes().Count > 0)
{
    foreach (Stroke strk in this.inkCanv.GetSelectedStrokes())
        this.inkCanv.Strokes.Remove(strk);
}

Select Ink

Recall earlier for the Select Cut, Copy, Paste And Delete operations, we had to actually have some Ink selected. Well how do we select some Ink. As I stated that this can be done in 2 ways, you may either use the Select button (this option) or the current stylus may be changed to be in select mode. So let's have a look at how to select all Ink. It's very easy:

this.inkCanv.Select(this.inkCanv.Strokes);

Format Ink

Formatting Ink relies on you first having selected some Ink to format. So assuming you have some Ink (Strokes) selected when you use the Format Ink button, you will be shown the color picker window as shown below in the Stylus Color section, that window will enable you to change the Strokes attributes.

The code for the Format button is simply going to try and get the color of the 1st Stroke, and then show the dialog window where we can pick a new color for the selected Strokes.

StylusSettings dlg = new StylusSettings();
dlg.Owner = this;

// Try getting the DrawingAttributes of the first selected stroke.
StrokeCollection strokes = this.inkCanv.GetSelectedStrokes();

if (strokes.Count > 0)
    dlg.DrawingAttributes = strokes[0].DrawingAttributes;
else
    dlg.DrawingAttributes = this.inkCanv.DefaultDrawingAttributes;

if ((bool)dlg.ShowDialog().GetValueOrDefault())
{
    // Set the DrawingAttributes of all the selected strokes.
    foreach (Stroke strk in strokes)
        strk.DrawingAttributes = dlg.DrawingAttributes;
}

Stylus color

In order for the user to control what color and how the Ink should be applied there is a second XAML window that is used, this is called "StylusSettings.xaml" and it contains a UniformGrid control with buttons which simply have their backgrounds set to a particular Brush color out of the collection of System.Brushes.

The iteration of the System.Brushes is done using Reflection.

C#
private void createGridOfColor()
{
    PropertyInfo[] props = typeof(Brushes).GetProperties(BindingFlags.Public |
                                          BindingFlags.Static);
    // Create individual items
    foreach (PropertyInfo p in props)
    {
        Button b = new Button();
        b.Background = (SolidColorBrush)p.GetValue(null, null);
        b.Foreground = Brushes.Transparent;
        b.BorderBrush=Brushes.Transparent;
        b.Click += new RoutedEventHandler(b_Click);
        this.ugColors.Children.Add(b);
    }
}

Also this page is responsible for showing and setting the current Ink values that will be used for drawing with. This is achieved by the use of a nice class called DrawingAttributes which can be both retrieved and set on the InkCanvas

C#
public DrawingAttributes DrawingAttributes
{
    set
    {
        chkPressure.IsChecked = value.IgnorePressure;
        chkHighlight.IsChecked = value.IsHighlighter;
        penWidth = value.Width;
        penHeight = value.Height;
        currColor = value.Color;
    }
    get
    {
        DrawingAttributes drawattr = new DrawingAttributes();
        drawattr.IgnorePressure = (bool)chkPressure.IsChecked;
        drawattr.Width=penWidth;
        drawattr.Height = penHeight;
        drawattr.IsHighlighter = (bool)chkHighlight.IsChecked;
        drawattr.Color = currColor;
        return drawattr;
    }
}

标签:笔迹,selected,some,inkcavas,Ink,DrawingAttributes,new,WPF,inkCanv
From: https://www.cnblogs.com/guangzhiruijie/p/17684324.html

相关文章

  • 【愚公系列】2023年09月 WPF控件专题 Slider控件详解
    (文章目录)前言WPF控件是WindowsPresentationFoundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见......
  • [WPF]使用HLSL实现百叶窗动效
    百叶窗动画是制作PPT时常用的动画之一,本文将通过实现百叶窗动画效果的例子介绍在WPF中如何使用ShaderEffect。ShaderEffect是使用高级着色器语言(HighLevelShadingLanguage,HLSL)事先制作好并且已经编译过的效果。先看下百叶窗动画实现效果:准备工作与实现编写和编译HLSL代码,创......
  • C#+WPF上位机开发课程(模块化与反应式编程)
    点击下载:C#+WPF上位机开发课程(模块化与反应式编程)提取码:ak72上位机是指可以直接发出操控命令的计算机,一般是PC,通常用于屏幕上显示各种信号变化(液压,水位,温度等),并将这些数据存储下来,供分析。 下位机是直接控制设备,获取设备状况的计算机,一般是PLC(ProgrammableLogicController)/单......
  • 界面控件DevExpress WPF(v23.2)下半年发展路线图
    本文主要概述了DevExpress官方在下半年(v23.2)中一些与DevExpressWPF相关的开发计划。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。DevExpressWPFv23.1正式版下载DevExpress技术交流群8......
  • 【愚公系列】2023年09月 WPF控件专题 Calendar控件详解
    (文章目录)前言WPF控件是WindowsPresentationFoundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见......
  • dotnet 读 WPF 源代码笔记 渲染层是如何将字符 GlyphRun 画出来的
    从业务代码构建出来GlyphRun对象,在WPF的渲染层里,如何利用GlyphRun提供的数据将字符在界面呈现出来。本文将和大家聊聊从WPF的渲染层获取到GlyphRun数据,到调用DirectX的各个渲染相关方法的过程,也就是WPF绘制文本字符的原理或者实现方法大家印象中的绘制一段文本是调......
  • dotnet 读 WPF 源代码笔记 聊聊 HwndWrapper
    我在阅读WPF源代码,在HwndWrapper的静态构造函数看到了申请了HwndWrapper.GetGCMemMessage这个Windows消息,好奇这个消息是什么功能的。通过阅读WPF源代码和写测试应用,了解到这是一个完全用来内部测试或调试的消息,没有任何业务上的功能在WPF的HwndWrapper的静态构造......
  • dotnet 读 WPF 源代码笔记 GlyphRun 的 DeviceFontName 的功能是什么
    在WPF里面的GlyphRun里,有一个令人迷惑的DeviceFontName属性,似乎给这个属性传入什么值,结果都不会有变更。通过阅读源代码,可以了解到,这是一个没什么用途的属性。本文将告诉大家这个属性的细节逻辑在上一篇博客WPF简单聊聊如何使用DrawGlyphRun绘制文本里面就提到如何创......
  • WPF学习 - 自定义窗体(二)
    上一篇文章写了如何创建自定义窗体:使用WindowChrome或者WindowStyle=“None”这两种方式。本文将讲述如何设置窗体的效果(以阴影效果为例),以及在效果模式下,窗体各功能的配合。一、窗体的空间范围:窗体的范围,就是白色区域部分:包括窗体的边框,标题栏,以及内部的空白部分。出了白色......
  • cefsharp - WinForms 和 Wpf 示例之间的巨大性能差异
    https://www.coder.work/article/7217456我注意到在使用 http://www.vsynctester.com 时CefSharp.WinForms.Example和CefSharp.Wpf.Example之间存在非常重要的性能差异(以FPS计)在我的显卡控制面板和CefExampleInit()中的设置中关闭VSync时settings.CefCommandLi......