• WPF InkCanvas 截图功能


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

     1.MainWindow.xaml

    1. "WPF_InkCanvas.ROI_InkCanvas"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:WPF_InkCanvas"
    7. mc:Ignorable="d"
    8. Title="ROI_InkCanvas" Height="450" Width="800" KeyDown="Window_KeyDown" KeyUp="Window_KeyUp" Background="Transparent" >
    9. "grid" KeyUp="Window_KeyUp" Background="#FF313030" MouseLeftButtonUp="inkCanvasMeasure_MouseLeftButtonUp">
    10. "auto"/>
    11. "imgMeasure" HorizontalAlignment="Center" Stretch="Uniform" />
    12. "inkCanvasMeasure" EditingMode="None" Background="Transparent" Strokes="{Binding InkStrokes, Mode=TwoWay}" HorizontalAlignment="Center"
    13. Width="{Binding ElementName=imgMeasure, Path=ActualWidth}" Height="{Binding ElementName=imgMeasure, Path=ActualHeight}"
    14. MouseDown="InkCanvasMeasure_MouseDown" MouseMove="InkCanvasMeasure_MouseMove" MouseLeftButtonUp="inkCanvasMeasure_MouseLeftButtonUp">
    15. "sp" Background="White" Width="50" Height="30" Visibility="Collapsed">
    16. "#67C23A" Width="20" Height="15" Stretch="Fill" Data="M384 690l452-452 60 60-512 512-238-238 60-60z"/>
    17. "1" Orientation="Horizontal" Name="st">
    18. "btnSquare" Content="Draw Square" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="DrawSquare_Click"/>
    19. "btnEllipse" Content="Draw Ellipse" Margin="5" HorizontalAlignment="Left" FontSize="20" Click="DrawEllipse_Click"/>

     2.MainWindow.xaml.cs

    1. using Microsoft.Win32;
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Drawing.Imaging;
    5. using System.IO;
    6. using System.Linq;
    7. using System.Runtime.InteropServices;
    8. using System.Text;
    9. using System.Threading.Tasks;
    10. using System.Windows;
    11. using System.Windows.Controls;
    12. using System.Windows.Data;
    13. using System.Windows.Documents;
    14. using System.Windows.Ink;
    15. using System.Windows.Input;
    16. using System.Windows.Media;
    17. using System.Windows.Media.Imaging;
    18. using System.Windows.Shapes;
    19. using Tend.UAC.Controls;
    20. namespace WPF_InkCanvas
    21. {
    22. ///
    23. /// ROI_InkCanvas.xaml 的交互逻辑
    24. ///
    25. public partial class ROI_InkCanvas : Window
    26. {
    27. private ViewModel viewModel;
    28. private System.Windows.Point iniP;
    29. private System.Windows.Point endP;
    30. public ROI_InkCanvas()
    31. {
    32. InitializeComponent();
    33. this.WindowStyle = WindowStyle.None;
    34. this.AllowsTransparency = true;
    35. //grid.Opacity = 0.7;
    36. imgMeasure.Opacity = 1;
    37. this.Background = new SolidColorBrush(Colors.Gray);// new SolidColorBrush(Colors.Transparent);
    38. grid.Background = new SolidColorBrush(Colors.Transparent);
    39. btnSquare.IsChecked = true;
    40. //设置画笔属性
    41. DrawingAttributes drawingAttributes = new DrawingAttributes
    42. {
    43. Color = Colors.LightGreen,
    44. Width = 1,
    45. Height = 1,
    46. StylusTip = StylusTip.Rectangle,//设置墨迹触笔的形状
    47. //FitToCurve = true,
    48. IsHighlighter = false,
    49. IgnorePressure = true,
    50. };
    51. inkCanvasMeasure.DefaultDrawingAttributes = drawingAttributes;
    52. inkCanvasMeasure.AllowDrop = true;
    53. viewModel = new ViewModel
    54. {
    55. //MeaInfo = "测试······",
    56. InkStrokes = new StrokeCollection(),
    57. };
    58. DataContext = viewModel;
    59. }
    60. private void OpenFile_Click(object sender, RoutedEventArgs e)
    61. {
    62. OpenFileDialog openDialog = new OpenFileDialog
    63. {
    64. Filter = "Image Files (*.bmp)|*.bmp|Image Files (*.jpg)|*.jpg|Image Files (*.png)|*.png",
    65. Title = "Open Image File"
    66. };
    67. if (openDialog.ShowDialog() == true)
    68. {
    69. BitmapImage image = new BitmapImage();
    70. image.BeginInit();
    71. image.UriSource = new Uri(openDialog.FileName, UriKind.RelativeOrAbsolute);
    72. image.EndInit();
    73. imgMeasure.Source = image;
    74. this.image = image;
    75. }
    76. }
    77. private BitmapImage image;
    78. private void DrawSquare_Click(object sender, RoutedEventArgs e)
    79. {
    80. if (btnSquare.IsChecked == true)
    81. {
    82. btnEllipse.IsChecked = false;
    83. }
    84. }
    85. public Byte[] ByteFromImage(System.Windows.Media.Imaging.BitmapImage imageSource)
    86. {
    87. Stream stream = imageSource.StreamSource;
    88. Byte[] imagebyte = null;
    89. if (stream != null && stream.Length > 0)
    90. {
    91. using (BinaryReader br = new BinaryReader(stream))
    92. {
    93. imagebyte = br.ReadBytes((Int32)stream.Length);
    94. }
    95. }
    96. return imagebyte;
    97. }
    98. public byte[] getImgByte(System.Drawing.Image image) //调用方法转字节
    99. {
    100. MemoryStream ms = new MemoryStream();
    101. try
    102. {
    103. image.Save(ms, ImageFormat.Bmp);
    104. byte[] bt = ms.GetBuffer();
    105. return bt;
    106. }
    107. catch (Exception ex)
    108. {
    109. throw ex;
    110. }
    111. finally
    112. {
    113. ms.Close();
    114. }
    115. }
    116. #region BitmapImage 转为byte[]
    117. ///
    118. /// BitmapImage 转为byte[]
    119. ///
    120. /// BitmapImage 对象
    121. /// byte[] 数组
    122. public byte[] BitmapImageToByteArray(BitmapImage bitmapImage)
    123. {
    124. byte[] buffer = new byte[] { };
    125. try
    126. {
    127. Stream stream = bitmapImage.StreamSource;
    128. if (stream != null && stream.Length > 0)
    129. {
    130. stream.Position = 0;
    131. using (BinaryReader binary = new BinaryReader(stream))
    132. {
    133. buffer = binary.ReadBytes((int)stream.Length);
    134. }
    135. }
    136. }
    137. catch (Exception ex)
    138. {
    139. }
    140. return buffer;
    141. }
    142. #endregion
    143. private void DrawEllipse_Click(object sender, RoutedEventArgs e)
    144. {
    145. var r = "";
    146. System.Drawing.Bitmap b = new System.Drawing.Bitmap(image.UriSource.LocalPath);
    147. MemoryStream ms = new MemoryStream();
    148. b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
    149. byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); 这两句都可以,至于区别么,下面有解释
    150. ms.Close();
    151. var w = new ImgCut(bytes);
    152. if (w.ShowDialog()==false) {
    153. MessageBox.Show(w.rate?.ToString());
    154. }
    155. //if (btnEllipse.IsChecked == true)
    156. //{
    157. // btnSquare.IsChecked = false;
    158. //}
    159. }
    160. private List GenerateEclipseGeometry(System.Windows.Point st, System.Windows.Point ed)
    161. {
    162. double a = 0.5 * (ed.X - st.X);
    163. double b = 0.5 * (ed.Y - st.Y);
    164. List pointList = new List();
    165. for (double r = 0; r <= 2 * Math.PI; r = r + 0.01)
    166. {
    167. 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)));
    168. }
    169. return pointList;
    170. }
    171. private void InkCanvasMeasure_MouseDown(object sender, MouseButtonEventArgs e)
    172. {
    173. if (e.LeftButton == MouseButtonState.Pressed)
    174. {
    175. iniP = e.GetPosition(inkCanvasMeasure);
    176. }
    177. }
    178. private void InkCanvasMeasure_MouseMove(object sender, MouseEventArgs e)
    179. {
    180. if (e.LeftButton == MouseButtonState.Pressed)
    181. {
    182. // Draw square
    183. if (btnSquare.IsChecked == true)
    184. {
    185. endP = e.GetPosition(inkCanvasMeasure);
    186. List pointList = new List
    187. {
    188. new System.Windows.Point(iniP.X, iniP.Y),
    189. new System.Windows.Point(iniP.X, endP.Y),
    190. new System.Windows.Point(endP.X, endP.Y),
    191. new System.Windows.Point(endP.X, iniP.Y),
    192. new System.Windows.Point(iniP.X, iniP.Y),
    193. };
    194. StylusPointCollection point = new StylusPointCollection(pointList);
    195. Stroke stroke = new Stroke(point)
    196. {
    197. DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
    198. };
    199. viewModel.InkStrokes.Clear();
    200. viewModel.InkStrokes.Add(stroke);
    201. }
    202. // Draw Eclipse
    203. else if (btnEllipse.IsChecked == true)
    204. {
    205. endP = e.GetPosition(inkCanvasMeasure);
    206. List pointList = GenerateEclipseGeometry(iniP, endP);
    207. StylusPointCollection point = new StylusPointCollection(pointList);
    208. Stroke stroke = new Stroke(point)
    209. {
    210. DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
    211. };
    212. viewModel.InkStrokes.Clear();
    213. viewModel.InkStrokes.Add(stroke);
    214. }
    215. }
    216. }
    217. public WindowState SaveWindowState { get; set; }
    218. public WindowStyle SaveWindowStyle { get; set; }
    219. public ResizeMode SaveResizeMode { get; set; }
    220. public bool SaveTopmost { get; set; }
    221. public double SaveLeft { get; set; }
    222. public double SaveTop { get; set; }
    223. public double SaveWidth { get; set; }
    224. public double SaveHeight { get; set; }
    225. private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    226. {
    227. //记录当前窗口状态
    228. this.SaveWindowState = this.WindowState;
    229. this.SaveWindowStyle = this.WindowStyle;
    230. this.SaveResizeMode = this.ResizeMode;
    231. this.SaveTopmost = this.Topmost;
    232. this.SaveLeft = this.Left;
    233. this.SaveTop = this.Top;
    234. this.SaveWidth = this.Width;
    235. this.SaveHeight = this.Height;
    236. if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.H)
    237. {
    238. st.Visibility = Visibility.Collapsed;
    239. //同时按下了Ctrl + H键(H要最后按,因为判断了此次事件的e.Key)
    240. //修饰键只能按下Ctrl,如果还同时按下了其他修饰键,则不会进入
    241. // 设置全屏
    242. this.WindowState = System.Windows.WindowState.Normal;//还原窗口(非最小化和最大化)
    243. this.WindowStyle = System.Windows.WindowStyle.None;//仅工作区可见,不显示标题栏和边框
    244. this.ResizeMode = System.Windows.ResizeMode.NoResize;//不显示最大化和最小化按钮
    245. //this.Topmost = true;
    246. this.Left = 0.0;
    247. this.Top = 0.0;
    248. this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
    249. this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
    250. }
    251. else if (e.Key == Key.Escape)
    252. {
    253. st.Visibility = Visibility.Visible;
    254. this.WindowState = this.SaveWindowState;
    255. this.WindowStyle = this.SaveWindowStyle;
    256. this.ResizeMode = this.SaveResizeMode;
    257. this.Topmost = this.SaveTopmost;
    258. this.Left = this.SaveLeft;
    259. this.Top = this.SaveTop;
    260. this.Width = this.SaveWidth;
    261. this.Height = this.SaveHeight;
    262. }
    263. }
    264. private void Window_Loaded(object sender, RoutedEventArgs e)
    265. {
    266. this.WindowState = System.Windows.WindowState.Normal;//还原窗口(非最小化和最大化)
    267. this.WindowStyle = System.Windows.WindowStyle.None; //仅工作区可见,不显示标题栏和边框
    268. this.ResizeMode = System.Windows.ResizeMode.NoResize;//不显示最大化和最小化按钮
    269. this.Topmost = true; //窗口在最前
    270. this.Left = 0.0;
    271. this.Top = 0.0;
    272. this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
    273. this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
    274. }
    275. private void Window_KeyUp(object sender, KeyEventArgs e)
    276. {
    277. if (e.Key == Key.Escape)
    278. {
    279. st.Visibility = Visibility.Visible;
    280. this.WindowState = this.SaveWindowState;
    281. this.WindowStyle = this.SaveWindowStyle;
    282. this.ResizeMode = this.SaveResizeMode;
    283. this.Topmost = this.SaveTopmost;
    284. this.Left = this.SaveLeft;
    285. this.Top = this.SaveTop;
    286. this.Width = this.SaveWidth;
    287. this.Height = this.SaveHeight;
    288. }
    289. }
    290. private void inkCanvasMeasure_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    291. {
    292. Point zs;//左上点
    293. Point yx;//右下点
    294. if (endP.X > iniP.X)
    295. {
    296. zs = iniP;
    297. yx = endP;
    298. }
    299. else
    300. {
    301. zs = endP;
    302. yx = iniP;
    303. }
    304. var pw = imgMeasure.ActualWidth;//图片宽
    305. var ph = imgMeasure.ActualHeight; //图片高
    306. if (yx.Y + 34 < ph)
    307. sp.Margin = new Thickness(yx.X - 50, yx.Y + 4, 0, 0);
    308. else
    309. sp.Margin = new Thickness(yx.X - 50, ph - 34, 0, 0);
    310. sp.Visibility = Visibility.Visible;
    311. }
    312. private void PART_ButtonComplete_Click(object sender, RoutedEventArgs e)
    313. {
    314. Point zs;//左上点
    315. Point yx;//右下点
    316. if (endP.X > iniP.X)
    317. {
    318. zs = iniP;
    319. yx = endP;
    320. }
    321. else
    322. {
    323. zs = endP;
    324. yx = iniP;
    325. }
    326. var pw = imgMeasure.ActualWidth;//图片宽
    327. var ph = imgMeasure.ActualHeight; //图片高
    328. 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));
    329. }
    330. }
    331. }

    3.ViewModel.cs

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Linq;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. using System.Windows.Ink;
    8. namespace WPF_InkCanvas
    9. {
    10. class ViewModel : INotifyPropertyChanged
    11. {
    12. public event PropertyChangedEventHandler PropertyChanged;
    13. protected virtual void OnPropertyChanged(string propertyName = null)
    14. {
    15. if (PropertyChanged != null)
    16. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
    17. }
    18. private string meaInfo;
    19. public string MeaInfo
    20. {
    21. get => meaInfo;
    22. set
    23. {
    24. meaInfo = value;
    25. OnPropertyChanged("MeaInfo");
    26. }
    27. }
    28. private StrokeCollection inkStrokes;
    29. public StrokeCollection InkStrokes
    30. {
    31. get { return inkStrokes; }
    32. set
    33. {
    34. inkStrokes = value;
    35. OnPropertyChanged("InkStrokes");
    36. }
    37. }
    38. }
    39. }

  • 相关阅读:
    自然资源-做好用地用海国土空间规划符合性审查
    java计算机毕业设计作业自动评阅系统的设计和开发源码+数据库+系统+lw文档+mybatis+运行部署
    最新Jn建站系统2.0 已集成各类源码 【附视频安装教程】
    第四十章 SOAP 会话管理
    【Linux】项目日志——输出重定向
    光伏发电站远程监测无线解决方案,时刻保持电力十足
    DOSBox解决CPU从内存单元中要读取数据
    Go 语言高级网络编程
    hadoop集群,namenode启动,所有的datanode无法启动
    [附源码]计算机毕业设计springboot创新创业管理系统
  • 原文地址:https://blog.csdn.net/weixin_38110122/article/details/126586351