//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&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