首页 > 其他分享 >WPF InkCanvas selection mode, save all/selected strokes, load strokes file, save inkcanvas as image

WPF InkCanvas selection mode, save all/selected strokes, load strokes file, save inkcanvas as image

时间:2024-09-26 12:01:32浏览次数:1  
标签:load strokes System Windows inkCvs dialog new using save

//xaml
<Window x:Class="WpfApp416.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp416"
        mc:Ignorable="d"
        WindowState="Maximized"
        KeyDown="Window_KeyDown"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ToolBar Grid.Row="0">
            <!--<Button Content="Edit Mode" Click="EditModeClick" Width="150"/>
            <Button Content="Erase Mode" Click="EraseModeClick" Width="150"/>-->
            <Button Content="Select Mode" Click="SelectModeClick" Width="150"/>
            <Button Content="Remove Selected" Click="RemoveSelectedClick" Width="150"/>
            <Button Content="Change Color" Click="ChangeColorClick" Width="150"/>
            <Button Content="Save All" Click="SaveAllClick" Width="150"/>
            <Button Content="Save Selected" Click="SaveSelectedClick" Width="150"/>
            <Button Content="Load Strokes" Click="LoadStrokesClick" Width="150"/>
            <Button Content="Save As Picture" Click="SavePictureClick" Width="150"/>
        </ToolBar>
        <InkCanvas x:Name="inkCvs" Grid.Row="1" SelectionChanged="inkCvs_SelectionChanged"
                   Gesture="inkCvs_Gesture" >           
            <Image Source="https://img1.baidu.com/it/u=3991277133,2041185316&amp;fm=253"
                   Width="{Binding ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" 
                   Height="{Binding ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
        </InkCanvas>
    </Grid>
</Window>


//cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using Newtonsoft.Json;

namespace WpfApp416
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitInkCanvas();
            
        }

        private void InitInkCanvas()
        {
            inkCvs.DefaultDrawingAttributes.Color = Colors.Red;
            inkCvs.DefaultDrawingAttributes.Width = 10;
            inkCvs.DefaultDrawingAttributes.Height = 10;
            //inkCvs.DefaultDrawingAttributes.IsHighlighter = true;
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.C)
            {
                var msgResult=MessageBox.Show("Are you sure to exit the window?","Exit",
                    MessageBoxButton.YesNo,MessageBoxImage.Question, MessageBoxResult.Yes);
                if(msgResult == MessageBoxResult.Yes)
                {
                    this.Close();
                }
            }
        }

        private void EditModeClick(object sender, RoutedEventArgs e)
        {
            inkCvs.EditingMode = InkCanvasEditingMode.Ink;
        }

        private void EraseModeClick(object sender, RoutedEventArgs e)
        {
            inkCvs.EditingMode = InkCanvasEditingMode.EraseByStroke;
        }

        private void SelectModeClick(object sender, RoutedEventArgs e)
        {
            inkCvs.EditingMode=InkCanvasEditingMode.Select;
        }

        private void ChangeColorClick(object sender, RoutedEventArgs e)
        {
            UCColorPicker ucColor = new UCColorPicker();
            //ucColor.Show();
            
            if(ucColor.ShowDialog()==true)
            {
                Color cl = new Color();
                cl.A = ucColor.UCAlpha;
                cl.R = ucColor.UCRed;
                cl.G = ucColor.UCGreen;
                cl.B = ucColor.UCBlue;

                inkCvs.DefaultDrawingAttributes.Color = cl;
            }
           

        }

        private void inkCvs_SelectionChanged(object sender, EventArgs e)
        {
            

        }

        private void SaveAllClick(object sender, RoutedEventArgs e)
        {
            var allStrokes = inkCvs.Strokes;
            if (allStrokes != null && allStrokes.Any())
            {
                SaveFileDialog dialog = new SaveFileDialog();
                dialog.Filter = "ISF Files|*.isf|All Files|*.*";
                dialog.FileName = $"All{DateTime.Now.ToString("yyyyMMddHHmmddssffff")}_{Guid.NewGuid().ToString("N")}.isf";
                if (dialog.ShowDialog() == true)
                { 
                    if (dialog.ShowDialog() == true)
                    {
                        using (FileStream fs = new FileStream(dialog.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                        {
                            allStrokes.Save(fs);
                            MessageBox.Show($"Saved in {dialog.FileName}", "Save All Successfully!", MessageBoxButton.OK);
                        }
                    }
                }
            }
        }

        private void SaveSelectedClick(object sender, RoutedEventArgs e)
        {
            var selectedStrokes = inkCvs.GetSelectedStrokes();
            if (selectedStrokes != null && selectedStrokes.Any())
            {
                SaveFileDialog dialog = new SaveFileDialog();
                dialog.Filter = "ISF Files|*.isf|All Files|*.*";
                dialog.FileName = $"Selected{DateTime.Now.ToString("yyyyMMddHHmmddssffff")}_{Guid.NewGuid().ToString("N")}.isf";
                
                if(dialog.ShowDialog()==true)
                {
                    using (FileStream fs = new FileStream(dialog.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        selectedStrokes.Save(fs);
                        MessageBox.Show($"Saved in {dialog.FileName}", "Save Selected Successfully!", MessageBoxButton.OK);
                    }
                }
            }
        }

        private void RemoveSelectedClick(object sender, RoutedEventArgs e)
        {
            var seletcedStrokes=inkCvs.GetSelectedStrokes();
            if(seletcedStrokes != null && seletcedStrokes.Any())
            {
                inkCvs.Strokes.Remove(seletcedStrokes);
            }
        }

        private void inkCvs_Gesture(object sender, InkCanvasGestureEventArgs e)
        {

        }

        private void LoadStrokesClick(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "ISF Files|*.isf|All Files|*.*";
            if (dialog.ShowDialog()==true)
            {
                if(File.Exists(dialog.FileName))
                {
                    using (FileStream fs = new FileStream(dialog.FileName, FileMode.Open))
                    {
                        StrokeCollection strokes = new StrokeCollection(fs);
                        inkCvs.Strokes = strokes;
                    }
                }
            }
        }

        private void SavePictureClick(object sender, RoutedEventArgs e)
        {
            RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)inkCvs.ActualWidth,
    (int)inkCvs.ActualHeight, 96d, 96d, PixelFormats.Pbgra32);
            inkCvs.Measure(new Size((int)inkCvs.ActualWidth, (int)inkCvs.ActualHeight));
            inkCvs.Arrange(new Rect(new Size((int)inkCvs.ActualWidth, (int)inkCvs.ActualHeight)));
            renderBitmap.Render(inkCvs);

            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "JPG Files|*.jpg|PNG Files|*.png|All Files|*.*";
            dialog.FileName = $"Image_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.jpg";
            if(dialog.ShowDialog()==true)
            {
                using (FileStream fs = new FileStream(dialog.FileName, FileMode.Create))
                {
                    PngBitmapEncoder encoder = new PngBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
                    encoder.Save(fs);
                    MessageBox.Show($"Saved in {dialog.FileName}", "Save Image Successfully!", MessageBoxButton.OK);
                }
            }
        }
    }
}



//usercontrol.xaml
<Window x:Class="WpfApp416.UCColorPicker"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp416"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Window.Resources>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="FontSize" Value="30"/>
            <Setter Property="HorizontalAlignment" Value="Right"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
        </Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="FontSize" Value="30"/>
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
        </Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="FontSize" Value="30"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="Alpha:" HorizontalAlignment="Right"/>
        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding UCAlpha,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        <TextBlock Grid.Row="1" Grid.Column="0" Text="Red:"/>
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding UCRed,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        <TextBlock Grid.Row="2" Grid.Column="0" Text="Green:"/>
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding UCGreen,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        <TextBlock Grid.Row="3" Grid.Column="0" Text="Blue:"/>
        <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding UCBlue,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        <Button Grid.Row="4" Grid.Column="1" Content="OK" Click="ColorClick"/>
    </Grid>
</Window>


//usercontrol.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp416
{
    /// <summary>
    /// Interaction logic for UCColorPicker.xaml
    /// </summary>
    public partial class UCColorPicker : Window
    {
        public UCColorPicker()
        {
            InitializeComponent();
            this.DataContext = this;
        }



        public byte UCAlpha
        {
            get { return (byte)GetValue(UCAlphaProperty); }
            set { SetValue(UCAlphaProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCAlpha.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCAlphaProperty =
            DependencyProperty.Register("UCAlpha", typeof(byte), 
                typeof(UCColorPicker), new PropertyMetadata((byte)255));




        public byte UCRed
        {
            get { return (byte)GetValue(UCRedProperty); }
            set { SetValue(UCRedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCRed.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCRedProperty =
            DependencyProperty.Register("UCRed", typeof(byte),
                typeof(UCColorPicker), new PropertyMetadata((byte)0));




        public byte UCGreen
        {
            get { return (byte)GetValue(UCGreenProperty); }
            set { SetValue(UCGreenProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCGreen.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCGreenProperty =
            DependencyProperty.Register("UCGreen", typeof(byte), 
                typeof(UCColorPicker), new PropertyMetadata((byte)0));





        public byte UCBlue
        {
            get { return (byte)GetValue(UCBlueProperty); }
            set { SetValue(UCBlueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCBlue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCBlueProperty =
            DependencyProperty.Register("UCBlue", typeof(byte), 
                typeof(UCColorPicker), new PropertyMetadata((byte)0));

        private void ColorClick(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }
    }
}

 

 

//Select

 

 

//Remove Selected

 

 

//Save as image

 

标签:load,strokes,System,Windows,inkCvs,dialog,new,using,save
From: https://www.cnblogs.com/Fred1987/p/18433178

相关文章

  • nload实时监网络流量信息
    nload用于实时监控linux下网络流量信息,是命令行工具,用来监控网络的吞吐量。它使用两个图表数据来对进出站流量进行可视化。一、安装nload[root@localhost~]#yuminstallepel-release.noarch-y[root@localhost~]#yuminstallnload.x86_64-y二、命令nload详解1、命令......
  • COMPSCI 315 Web Server Workload Characterization
    WebServerWorkloadCharacterizationAssignment3and4,COMPSCI315Due:RefertothedeadlineonCanvas;SubmissionviaCanvas1IntroductionInternettrafficmeasurementinvolvescollectingnetworkdatathatcanbeanalyzedforseveralpurposessuchas......
  • 如何使用 pygame.image.load() 加载图像?
    我只是想知道语法。如何使用pygame.image.load()加载图像?举个例子,我想加载一个名为cat.png的图像-并输入这个pygame.image.load('cat.png')那么,图像cat.png应该保存在哪里?当然可以,让我们来分解一下如何使用Pygame加载图像。1.导入和初始化首先,你......
  • SpringBoot 整合 apache fileupload 轻松实现文件上传与下载(通用版)
    我们以Thymeleaf页面模板引擎为例,简单介绍利用apachefileupload工具实现文件上传的功能。2.1、添加相关依赖包首先创建一个基础的SpringBoot项目,并引入相关的依赖包。2.2、添加相关配置参数2.3、文件上传示例对应文件上传的Controller类,示例如下:importorg.apache.commons.fi......
  • SpringBoot 整合 apache fileupload 轻松实现文件上传与下载(通用版)
    我们以Thymeleaf页面模板引擎为例,简单介绍利用apachefileupload工具实现文件上传的功能。2.1、添加相关依赖包首先创建一个基础的SpringBoot项目,并引入相关的依赖包。2.2、添加相关配置参数2.3、文件上传示例对应文件上传的Controller类,示例如下:importorg.apache.commons.fi......
  • OverloadValueOf
    packagecom.shrimpking.t6;/***CreatedbyIntelliJIDEA.**@Author:Shrimpking*@create2024/9/1612:08*/publicclassOverloadValueOf{publicstaticvoidmain(String[]args){bytenumByte=12;shortnumShort=34;......
  • ShowPrintlnOverload
    packagecom.shrimpking.t6;/***CreatedbyIntelliJIDEA.**@Author:Shrimpking*@create2024/9/1612:14*/publicclassShowPrintlnOverload{publicstaticvoidmain(String[]args){System.out.println(123);//整型System......
  • dmloader.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个dmloader.dll文件(挑选合适的版本文件)把它......
  • 使用 Secrets Loader 轻松管理 Laravel 和 JS 项目
    跨各种环境管理api密钥、令牌和凭证等敏感数据可能非常棘手,尤其是在开发和部署应用程序时。确保秘密在需要时安全地存储和获取,而不是将它们硬编码到版本控制中,对于维护安全性至关重要。这就是我创建secretsloader的原因,这是一个bash脚本,可以动态地将awsssm和cloudforma......
  • Loadr,一种在 HTML 中无缝加载大图像的高效解决方案
    它是如何工作的:它首先从imgsrc加载低分辨率图像,然后在hr-srcatrbute中加载高分辨率图像,一旦加载,就会用高分辨率图像替换低分辨率图像。查看仓库,如果有星星就太棒了演示立即学习“前端免费学习笔记(深入)”;安装cdn使用cdn导入loadr。index.html<scriptsrc="htt......