WPF inkcavas 保存笔迹部分

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;
    }
}
posted @   多见多闻  阅读(86)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示