From 2afd51c78350e1c7f83195f93c212a7107433464 Mon Sep 17 00:00:00 2001 From: "DESKTOP-3BO4HSG\\ksat" Date: Mon, 9 Jan 2023 18:54:57 +0800 Subject: [PATCH] feat: add screenshot to image --- STranslate/STranslate.csproj | 3 + STranslate/Util/Util.cs | 31 ++++++ STranslate/View/ScreenShotWindow.xaml | 3 + STranslate/View/ScreenShotWindow.xaml.cs | 6 +- STranslate/ViewModel/MainVM.cs | 3 +- STranslate/ViewModel/ScreenShotVM.cs | 130 ++++++++++++++++++++++- STranslate/packages.config | 1 + 7 files changed, 174 insertions(+), 3 deletions(-) diff --git a/STranslate/STranslate.csproj b/STranslate/STranslate.csproj index 0d6d820..c53c735 100644 --- a/STranslate/STranslate.csproj +++ b/STranslate/STranslate.csproj @@ -78,6 +78,9 @@ + + ..\packages\WpfScreenHelper.2.1.0\lib\net40\WpfScreenHelper.dll + diff --git a/STranslate/Util/Util.cs b/STranslate/Util/Util.cs index 0b8b8d6..77f5b31 100644 --- a/STranslate/Util/Util.cs +++ b/STranslate/Util/Util.cs @@ -2,6 +2,7 @@ using STranslate.Model; using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Net.Http; using System.Security.Cryptography; @@ -9,6 +10,8 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; +using System.Windows; +using System.Windows.Media; namespace STranslate.Util { @@ -236,5 +239,33 @@ namespace STranslate.Util return strA_Z; } #endregion + + #region Screenshot + public static ImageBrush BitmapToImageBrush(Bitmap bmp) + { + ImageBrush brush = new ImageBrush(); + IntPtr hBitmap = bmp.GetHbitmap(); + ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( + hBitmap, + IntPtr.Zero, + Int32Rect.Empty, + System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); + brush.ImageSource = wpfBitmap; + //TODO: flush Memory + return brush; + } + /// + /// 清理内存 + /// + public static void FlushMemory() + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + Helper.NativeMethodHelper.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); + } + } + #endregion } } diff --git a/STranslate/View/ScreenShotWindow.xaml b/STranslate/View/ScreenShotWindow.xaml index f2243d9..9f1664e 100644 --- a/STranslate/View/ScreenShotWindow.xaml +++ b/STranslate/View/ScreenShotWindow.xaml @@ -34,6 +34,9 @@ + + + diff --git a/STranslate/View/ScreenShotWindow.xaml.cs b/STranslate/View/ScreenShotWindow.xaml.cs index cbc211f..9884b1d 100644 --- a/STranslate/View/ScreenShotWindow.xaml.cs +++ b/STranslate/View/ScreenShotWindow.xaml.cs @@ -22,9 +22,13 @@ namespace STranslate.View { public ScreenShotWindow() { + DataContext = new ScreenShotVM(this); + + var datas = (DataContext as ScreenShotVM).InitView1(); + InitializeComponent(); - DataContext = new ScreenShotVM(this); + (DataContext as ScreenShotVM).InitView2(datas); } } } diff --git a/STranslate/ViewModel/MainVM.cs b/STranslate/ViewModel/MainVM.cs index 8067598..3fde51c 100644 --- a/STranslate/ViewModel/MainVM.cs +++ b/STranslate/ViewModel/MainVM.cs @@ -329,7 +329,8 @@ namespace STranslate.ViewModel var ratio = (double)engStr.Length / text.Length; //3. 判断英文字符个数占第一步所有字符个数比例,若超过一半则判定原字符串为英文字符串,否则为中文字符串 - if (ratio > 0.5) + //TODO: 配置项 + if (ratio > 0.8) { return new Tuple(LanguageEnum.EN.GetDescription(), LanguageEnum.ZH.GetDescription()); } diff --git a/STranslate/ViewModel/ScreenShotVM.cs b/STranslate/ViewModel/ScreenShotVM.cs index 05c9d9a..b534071 100644 --- a/STranslate/ViewModel/ScreenShotVM.cs +++ b/STranslate/ViewModel/ScreenShotVM.cs @@ -1,16 +1,22 @@ using STranslate.Helper; using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; using System.Windows.Input; namespace STranslate.ViewModel { public class ScreenShotVM : BaseVM { + /// + /// reference https://github.com/NPCDW/WpfTool + /// + /// public ScreenShotVM(Window ui) { _ScreenShotWin = ui; @@ -19,14 +25,136 @@ namespace STranslate.ViewModel _ScreenShotWin.Close(); }); + //鼠标移动 + MouseMoveCmd = new RelayCommand((_) => true, (_) => + { + if (MouseDown) + { + System.Windows.Point CurrentPoint = Mouse.GetPosition(_ScreenShotWin); + Rectangle = new Rect(StartPoint, CurrentPoint); + Canvas.SetLeft(_ScreenShotWin.FindName("LeftMask") as System.Windows.Shapes.Rectangle, 0); + Canvas.SetTop(_ScreenShotWin.FindName("LeftMask") as System.Windows.Shapes.Rectangle, 0); + (_ScreenShotWin.FindName("LeftMask") as System.Windows.Shapes.Rectangle).Width = Rectangle.X; + (_ScreenShotWin.FindName("LeftMask") as System.Windows.Shapes.Rectangle).Height = bitmap.Height; + + Canvas.SetLeft(_ScreenShotWin.FindName("RightMask") as System.Windows.Shapes.Rectangle, Rectangle.Left + Rectangle.Width); + Canvas.SetTop(_ScreenShotWin.FindName("RightMask") as System.Windows.Shapes.Rectangle, 0); + (_ScreenShotWin.FindName("RightMask") as System.Windows.Shapes.Rectangle).Width = bitmap.Width - Rectangle.Left - Rectangle.Width; + (_ScreenShotWin.FindName("RightMask") as System.Windows.Shapes.Rectangle).Height = bitmap.Height; + + Canvas.SetLeft(_ScreenShotWin.FindName("UpMask") as System.Windows.Shapes.Rectangle, Rectangle.Left); + Canvas.SetTop(_ScreenShotWin.FindName("UpMask") as System.Windows.Shapes.Rectangle, 0); + (_ScreenShotWin.FindName("UpMask") as System.Windows.Shapes.Rectangle).Width = Rectangle.Width; + (_ScreenShotWin.FindName("UpMask") as System.Windows.Shapes.Rectangle).Height = Rectangle.Y; + + Canvas.SetLeft(_ScreenShotWin.FindName("DownMask") as System.Windows.Shapes.Rectangle, Rectangle.Left); + Canvas.SetTop(_ScreenShotWin.FindName("DownMask") as System.Windows.Shapes.Rectangle, Rectangle.Y + Rectangle.Height); + (_ScreenShotWin.FindName("DownMask") as System.Windows.Shapes.Rectangle).Width = Rectangle.Width; + (_ScreenShotWin.FindName("DownMask") as System.Windows.Shapes.Rectangle).Height = bitmap.Height - Rectangle.Height - Rectangle.Y; + } + }); + + //左键Down + MouseLeftDownCmd = new RelayCommand((_) => true, (_) => + { + MouseDown = true; + StartPoint = Mouse.GetPosition(_ScreenShotWin); + }); + + //左键Up + MouseLeftUpCmd = new RelayCommand((_) => true, (_) => + { + MouseDown = false; + + int x = (int)(Rectangle.X * dpiScale); + int y = (int)(Rectangle.Y * dpiScale); + int width = (int)(Rectangle.Width * dpiScale); + int height = (int)(Rectangle.Height * dpiScale); + if (width <= 0 || height <= 0) + { + return; + } + Bitmap bmpOut = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + Graphics g = Graphics.FromImage(bmpOut); + g.DrawImage(bitmap, + new Rectangle(0, 0, width, height), + new Rectangle(x, y, width, height), + GraphicsUnit.Pixel); + + _ScreenShotWin.Close(); + + + TestSaveBmp(bmpOut); + }); + + ClosedCmd = new RelayCommand((_) => true, (_) => + { + Util.Util.FlushMemory(); + }); + } + + private void TestSaveBmp(Bitmap bmp) + { + bmp.Save("D:\\a.png", System.Drawing.Imaging.ImageFormat.Bmp); + } + + public Tuple InitView1() + { + // 获取鼠标所在屏幕 + System.Drawing.Point ms = System.Windows.Forms.Control.MousePosition; + Rect bounds = new Rect(); + int x = 0, y = 0, width = 0, height = 0; + foreach (WpfScreenHelper.Screen screen in WpfScreenHelper.Screen.AllScreens) + { + bounds = screen.WpfBounds; + dpiScale = screen.ScaleFactor; + x = (int)(bounds.X * dpiScale); + y = (int)(bounds.Y * dpiScale); + width = (int)(bounds.Width * dpiScale); + height = (int)(bounds.Height * dpiScale); + if (x <= ms.X && ms.X < x + width && y <= ms.Y && ms.Y < y + height) + { + break; + } + } + return new Tuple(bounds, x, y, width, height); + } + public void InitView2(Tuple tuple) + { + // 设置窗体位置、大小(实际宽高,单位unit) + _ScreenShotWin.Top = tuple.Item1.X; + _ScreenShotWin.Left = tuple.Item1.Y; + _ScreenShotWin.Width = tuple.Item1.Width; + _ScreenShotWin.Height = tuple.Item1.Height; + + // 设置遮罩 + Canvas.SetLeft(_ScreenShotWin, tuple.Item1.X); + Canvas.SetTop(_ScreenShotWin, tuple.Item1.Y); + (_ScreenShotWin.FindName("LeftMask") as System.Windows.Shapes.Rectangle).Width = tuple.Item1.Width; + (_ScreenShotWin.FindName("LeftMask") as System.Windows.Shapes.Rectangle).Height = tuple.Item1.Height; + + // 设置窗体背景(像素宽高,单位px) + bitmap = new Bitmap(tuple.Item4, tuple.Item5); + using (Graphics g = Graphics.FromImage(bitmap)) + { + g.CopyFromScreen(tuple.Item2, tuple.Item3, 0, 0, new System.Drawing.Size(tuple.Item4, tuple.Item5), CopyPixelOperation.SourceCopy); + } + _ScreenShotWin.Background = Util.Util.BitmapToImageBrush(bitmap); } public ICommand EscCmd { get; private set; } public ICommand MouseMoveCmd { get; private set; } public ICommand MouseLeftDownCmd { get; private set; } public ICommand MouseLeftUpCmd { get; private set; } + public ICommand ClosedCmd { get; private set; } + + private Window _ScreenShotWin; //Window + private Rect Rectangle = new Rect(); //保存的矩形 + private System.Windows.Point StartPoint; //鼠标按下的点 + private bool MouseDown; //鼠标是否被按下 + private Bitmap bitmap; // 截屏图片 + private double dpiScale = 1; - private Window _ScreenShotWin; } } diff --git a/STranslate/packages.config b/STranslate/packages.config index 56e9861..e2754e3 100644 --- a/STranslate/packages.config +++ b/STranslate/packages.config @@ -3,4 +3,5 @@ + \ No newline at end of file