此功能用了WPF的InkCanvas,鼠标画矩形,沟是确定,后台多余的代码可以不看,可以取四个角的坐标

1.MainWindow.xaml
"WPF_InkCanvas.ROI_InkCanvas" - 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:WPF_InkCanvas"
- mc:Ignorable="d"
- Title="ROI_InkCanvas" Height="450" Width="800" KeyDown="Window_KeyDown" KeyUp="Window_KeyUp" Background="Transparent" >
-
-
-
-
-
-
"grid" KeyUp="Window_KeyUp" Background="#FF313030" MouseLeftButtonUp="inkCanvasMeasure_MouseLeftButtonUp"> -
-
-
"auto"/> -
-
"imgMeasure" HorizontalAlignment="Center" Stretch="Uniform" /> -
"inkCanvasMeasure" EditingMode="None" Background="Transparent" Strokes="{Binding InkStrokes, Mode=TwoWay}" HorizontalAlignment="Center" - Width="{Binding ElementName=imgMeasure, Path=ActualWidth}" Height="{Binding ElementName=imgMeasure, Path=ActualHeight}"
- MouseDown="InkCanvasMeasure_MouseDown" MouseMove="InkCanvasMeasure_MouseMove" MouseLeftButtonUp="inkCanvasMeasure_MouseLeftButtonUp">
-
"sp" Background="White" Width="50" Height="30" Visibility="Collapsed"> -
-
-
"#67C23A" Width="20" Height="15" Stretch="Fill" Data="M384 690l452-452 60 60-512 512-238-238 60-60z"/> -
-
-
-
-
-
"1" Orientation="Horizontal" Name="st"> -
-
"btnSquare" Content="Draw Square" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="DrawSquare_Click"/> -
"btnEllipse" Content="Draw Ellipse" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="DrawEllipse_Click"/> -
-
-
2.MainWindow.xaml.cs
- using Microsoft.Win32;
- using System;
- using System.Collections.Generic;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Linq;
- using System.Runtime.InteropServices;
- 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.Shapes;
- using Tend.UAC.Controls;
-
- namespace WPF_InkCanvas
- {
- ///
- /// ROI_InkCanvas.xaml 的交互逻辑
- ///
- public partial class ROI_InkCanvas : Window
- {
- private ViewModel viewModel;
- private System.Windows.Point iniP;
- private System.Windows.Point endP;
-
- public ROI_InkCanvas()
- {
- InitializeComponent();
- this.WindowStyle = WindowStyle.None;
- this.AllowsTransparency = true;
- //grid.Opacity = 0.7;
- imgMeasure.Opacity = 1;
- this.Background = new SolidColorBrush(Colors.Gray);// new SolidColorBrush(Colors.Transparent);
- grid.Background = new SolidColorBrush(Colors.Transparent);
- btnSquare.IsChecked = true;
- //设置画笔属性
- DrawingAttributes drawingAttributes = new DrawingAttributes
- {
- Color = Colors.LightGreen,
- Width = 1,
- Height = 1,
- StylusTip = StylusTip.Rectangle,//设置墨迹触笔的形状
- //FitToCurve = true,
- IsHighlighter = false,
- IgnorePressure = true,
-
- };
- inkCanvasMeasure.DefaultDrawingAttributes = drawingAttributes;
- inkCanvasMeasure.AllowDrop = true;
-
- viewModel = new ViewModel
- {
- //MeaInfo = "测试······",
- InkStrokes = new StrokeCollection(),
- };
-
- DataContext = viewModel;
- }
-
- private void OpenFile_Click(object sender, RoutedEventArgs e)
- {
- OpenFileDialog openDialog = new OpenFileDialog
- {
- Filter = "Image Files (*.bmp)|*.bmp|Image Files (*.jpg)|*.jpg|Image Files (*.png)|*.png",
- Title = "Open Image File"
- };
- if (openDialog.ShowDialog() == true)
- {
- BitmapImage image = new BitmapImage();
- image.BeginInit();
- image.UriSource = new Uri(openDialog.FileName, UriKind.RelativeOrAbsolute);
- image.EndInit();
- imgMeasure.Source = image;
- this.image = image;
- }
- }
- private BitmapImage image;
- private void DrawSquare_Click(object sender, RoutedEventArgs e)
- {
- if (btnSquare.IsChecked == true)
- {
- btnEllipse.IsChecked = false;
- }
- }
- public Byte[] ByteFromImage(System.Windows.Media.Imaging.BitmapImage imageSource)
- {
- Stream stream = imageSource.StreamSource;
- Byte[] imagebyte = null;
- if (stream != null && stream.Length > 0)
- {
- using (BinaryReader br = new BinaryReader(stream))
- {
- imagebyte = br.ReadBytes((Int32)stream.Length);
- }
- }
-
- return imagebyte;
- }
- public byte[] getImgByte(System.Drawing.Image image) //调用方法转字节
-
- {
- MemoryStream ms = new MemoryStream();
- try
- {
- image.Save(ms, ImageFormat.Bmp);
- byte[] bt = ms.GetBuffer();
- return bt;
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- ms.Close();
- }
- }
-
- #region BitmapImage 转为byte[]
- ///
- /// BitmapImage 转为byte[]
- ///
- /// BitmapImage 对象
- ///
byte[] 数组 - public byte[] BitmapImageToByteArray(BitmapImage bitmapImage)
- {
- byte[] buffer = new byte[] { };
- try
- {
- Stream stream = bitmapImage.StreamSource;
- if (stream != null && stream.Length > 0)
- {
- stream.Position = 0;
- using (BinaryReader binary = new BinaryReader(stream))
- {
- buffer = binary.ReadBytes((int)stream.Length);
- }
- }
- }
- catch (Exception ex)
- {
-
- }
- return buffer;
- }
- #endregion
- private void DrawEllipse_Click(object sender, RoutedEventArgs e)
- {
- var r = "";
- System.Drawing.Bitmap b = new System.Drawing.Bitmap(image.UriSource.LocalPath);
- MemoryStream ms = new MemoryStream();
- b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
- byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); 这两句都可以,至于区别么,下面有解释
- ms.Close();
- var w = new ImgCut(bytes);
- if (w.ShowDialog()==false) {
- MessageBox.Show(w.rate?.ToString());
- }
-
- //if (btnEllipse.IsChecked == true)
- //{
- // btnSquare.IsChecked = false;
- //}
- }
-
- private List
GenerateEclipseGeometry(System.Windows.Point st, System.Windows.Point ed) - {
- double a = 0.5 * (ed.X - st.X);
- double b = 0.5 * (ed.Y - st.Y);
- List
pointList = new List(); - for (double r = 0; r <= 2 * Math.PI; r = r + 0.01)
- {
- pointList.Add(new System.Windows.Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), 0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
- }
- return pointList;
- }
- private void InkCanvasMeasure_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if (e.LeftButton == MouseButtonState.Pressed)
- {
- iniP = e.GetPosition(inkCanvasMeasure);
- }
- }
-
- private void InkCanvasMeasure_MouseMove(object sender, MouseEventArgs e)
- {
- if (e.LeftButton == MouseButtonState.Pressed)
- {
- // Draw square
- if (btnSquare.IsChecked == true)
- {
- endP = e.GetPosition(inkCanvasMeasure);
- List
pointList = new List - {
- new System.Windows.Point(iniP.X, iniP.Y),
- new System.Windows.Point(iniP.X, endP.Y),
- new System.Windows.Point(endP.X, endP.Y),
- new System.Windows.Point(endP.X, iniP.Y),
- new System.Windows.Point(iniP.X, iniP.Y),
- };
- StylusPointCollection point = new StylusPointCollection(pointList);
- Stroke stroke = new Stroke(point)
- {
- DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
- };
- viewModel.InkStrokes.Clear();
- viewModel.InkStrokes.Add(stroke);
- }
- // Draw Eclipse
- else if (btnEllipse.IsChecked == true)
- {
- endP = e.GetPosition(inkCanvasMeasure);
- List
pointList = GenerateEclipseGeometry(iniP, endP); - StylusPointCollection point = new StylusPointCollection(pointList);
- Stroke stroke = new Stroke(point)
- {
- DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
- };
- viewModel.InkStrokes.Clear();
- viewModel.InkStrokes.Add(stroke);
- }
- }
- }
- public WindowState SaveWindowState { get; set; }
- public WindowStyle SaveWindowStyle { get; set; }
- public ResizeMode SaveResizeMode { get; set; }
- public bool SaveTopmost { get; set; }
- public double SaveLeft { get; set; }
- public double SaveTop { get; set; }
- public double SaveWidth { get; set; }
- public double SaveHeight { get; set; }
- private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
- {
- //记录当前窗口状态
-
-
- this.SaveWindowState = this.WindowState;
-
-
- this.SaveWindowStyle = this.WindowStyle;
-
-
- this.SaveResizeMode = this.ResizeMode;
-
-
- this.SaveTopmost = this.Topmost;
-
-
- this.SaveLeft = this.Left;
-
-
- this.SaveTop = this.Top;
-
-
- this.SaveWidth = this.Width;
-
-
- this.SaveHeight = this.Height;
- if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.H)
- {
- st.Visibility = Visibility.Collapsed;
- //同时按下了Ctrl + H键(H要最后按,因为判断了此次事件的e.Key)
- //修饰键只能按下Ctrl,如果还同时按下了其他修饰键,则不会进入
- // 设置全屏
- this.WindowState = System.Windows.WindowState.Normal;//还原窗口(非最小化和最大化)
- this.WindowStyle = System.Windows.WindowStyle.None;//仅工作区可见,不显示标题栏和边框
- this.ResizeMode = System.Windows.ResizeMode.NoResize;//不显示最大化和最小化按钮
- //this.Topmost = true;
- this.Left = 0.0;
- this.Top = 0.0;
- this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
- this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
- }
- else if (e.Key == Key.Escape)
- {
- st.Visibility = Visibility.Visible;
-
- this.WindowState = this.SaveWindowState;
-
-
- this.WindowStyle = this.SaveWindowStyle;
-
-
- this.ResizeMode = this.SaveResizeMode;
-
-
- this.Topmost = this.SaveTopmost;
-
-
- this.Left = this.SaveLeft;
-
-
- this.Top = this.SaveTop;
-
-
- this.Width = this.SaveWidth;
-
-
- this.Height = this.SaveHeight;
- }
- }
- private void Window_Loaded(object sender, RoutedEventArgs e)
- {
- this.WindowState = System.Windows.WindowState.Normal;//还原窗口(非最小化和最大化)
- this.WindowStyle = System.Windows.WindowStyle.None; //仅工作区可见,不显示标题栏和边框
- this.ResizeMode = System.Windows.ResizeMode.NoResize;//不显示最大化和最小化按钮
- this.Topmost = true; //窗口在最前
-
- this.Left = 0.0;
- this.Top = 0.0;
- this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
- this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
- }
-
- private void Window_KeyUp(object sender, KeyEventArgs e)
- {
- if (e.Key == Key.Escape)
- {
- st.Visibility = Visibility.Visible;
-
- this.WindowState = this.SaveWindowState;
-
-
- this.WindowStyle = this.SaveWindowStyle;
-
-
- this.ResizeMode = this.SaveResizeMode;
-
-
- this.Topmost = this.SaveTopmost;
-
-
- this.Left = this.SaveLeft;
-
-
- this.Top = this.SaveTop;
-
-
- this.Width = this.SaveWidth;
-
-
- this.Height = this.SaveHeight;
- }
- }
-
- private void inkCanvasMeasure_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- Point zs;//左上点
- Point yx;//右下点
- if (endP.X > iniP.X)
- {
- zs = iniP;
- yx = endP;
- }
- else
- {
- zs = endP;
- yx = iniP;
- }
- var pw = imgMeasure.ActualWidth;//图片宽
- var ph = imgMeasure.ActualHeight; //图片高
- if (yx.Y + 34 < ph)
- sp.Margin = new Thickness(yx.X - 50, yx.Y + 4, 0, 0);
- else
- sp.Margin = new Thickness(yx.X - 50, ph - 34, 0, 0);
-
- sp.Visibility = Visibility.Visible;
- }
-
- private void PART_ButtonComplete_Click(object sender, RoutedEventArgs e)
- {
- Point zs;//左上点
- Point yx;//右下点
- if (endP.X > iniP.X)
- {
- zs = iniP;
- yx = endP;
- }
- else
- {
- zs = endP;
- yx = iniP;
- }
- var pw = imgMeasure.ActualWidth;//图片宽
- var ph = imgMeasure.ActualHeight; //图片高
- MessageBox.Show(Math.Round(zs.X / pw, 4) + "," + Math.Round(zs.Y / ph, 4) + "," + Math.Round(yx.X / pw, 4) + "," + Math.Round(yx.Y / ph, 4));
- }
-
- }
- }
3.ViewModel.cs
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Ink;
-
- namespace WPF_InkCanvas
- {
- class ViewModel : INotifyPropertyChanged
- {
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected virtual void OnPropertyChanged(string propertyName = null)
- {
- if (PropertyChanged != null)
- PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-
- private string meaInfo;
- public string MeaInfo
- {
- get => meaInfo;
- set
- {
- meaInfo = value;
- OnPropertyChanged("MeaInfo");
- }
- }
-
- private StrokeCollection inkStrokes;
- public StrokeCollection InkStrokes
- {
- get { return inkStrokes; }
- set
- {
- inkStrokes = value;
- OnPropertyChanged("InkStrokes");
- }
- }
- }
- }