From c2650e737b8ef58848dd8184266d1ca61d9fcb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=BC=9F?= Date: Thu, 23 Apr 2026 16:53:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E5=83=8F=E5=8C=BA=E5=9F=9F=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=8F=B3=E9=94=AE=E8=8F=9C=E5=8D=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- XplorePlane/Views/Main/ViewportPanelView.xaml | 16 +++- .../Views/Main/ViewportPanelView.xaml.cs | 83 ++++++++++++++++++- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml b/XplorePlane/Views/Main/ViewportPanelView.xaml index df7bd71..93561c1 100644 --- a/XplorePlane/Views/Main/ViewportPanelView.xaml +++ b/XplorePlane/Views/Main/ViewportPanelView.xaml @@ -41,8 +41,20 @@ - + Background="White"> + + + + + + + + + + + + + diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs index 48fa099..6b129a4 100644 --- a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs +++ b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using System.Windows.Media.Imaging; using System.Windows.Shapes; +using Microsoft.Win32; using XP.ImageProcessing.RoiControl.Controls; using XplorePlane.Events; using XplorePlane.ViewModels; @@ -204,10 +207,12 @@ namespace XplorePlane.Views StrokeThickness = 1.5, Cursor = Cursors.Hand }; + // 禁止测量点上弹出右键菜单 + dot.SetValue(ContextMenuService.IsEnabledProperty, false); dot.MouseLeftButtonDown += Dot_Down; dot.MouseMove += Dot_Move; dot.MouseLeftButtonUp += Dot_Up; - dot.MouseRightButtonDown += Dot_RightClick; + dot.PreviewMouseRightButtonUp += Dot_RightClick; return dot; } @@ -320,5 +325,81 @@ namespace XplorePlane.Views } #endregion + + #region 右键菜单 + + private void ZoomIn_Click(object sender, RoutedEventArgs e) => RoiCanvas.ZoomScale = Math.Min(10.0, RoiCanvas.ZoomScale * 1.2); + private void ZoomOut_Click(object sender, RoutedEventArgs e) => RoiCanvas.ZoomScale = Math.Max(0.1, RoiCanvas.ZoomScale / 1.2); + private void ResetView_Click(object sender, RoutedEventArgs e) => RoiCanvas.ResetView(); + + private void ClearAllMeasurements_Click(object sender, RoutedEventArgs e) + { + if (_measureOverlay != null) + { + _measureOverlay.Children.Clear(); + _groups.Clear(); + } + _pendingDot = null; + _pendingPoint = null; + + if (DataContext is ViewportPanelViewModel vm) + { + vm.ResetMeasurementState(); + vm.ImageInfo = "已清除所有测量"; + } + } + + private void SaveOriginalImage_Click(object sender, RoutedEventArgs e) + { + if (DataContext is not ViewportPanelViewModel vm || vm.ImageSource is not BitmapSource bitmap) + { + MessageBox.Show("当前没有可保存的图像", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return; + } + SaveBitmapToFile(bitmap, "保存原始图像"); + } + + private void SaveResultImage_Click(object sender, RoutedEventArgs e) + { + // 截取整个图像区域(含测量标注覆盖层) + var target = FindChildByName(RoiCanvas, "mainCanvas"); + if (target == null) + { + MessageBox.Show("当前没有可保存的图像", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return; + } + + var width = (int)target.ActualWidth; + var height = (int)target.ActualHeight; + if (width == 0 || height == 0) return; + + var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); + rtb.Render(target); + SaveBitmapToFile(rtb, "保存结果图像"); + } + + private static void SaveBitmapToFile(BitmapSource bitmap, string title) + { + var dialog = new SaveFileDialog + { + Title = title, + Filter = "PNG 图像|*.png|BMP 图像|*.bmp|JPEG 图像|*.jpg", + DefaultExt = ".png" + }; + if (dialog.ShowDialog() != true) return; + + BitmapEncoder encoder = System.IO.Path.GetExtension(dialog.FileName).ToLower() switch + { + ".bmp" => new BmpBitmapEncoder(), + ".jpg" or ".jpeg" => new JpegBitmapEncoder(), + _ => new PngBitmapEncoder() + }; + encoder.Frames.Add(BitmapFrame.Create(bitmap)); + + using var fs = new FileStream(dialog.FileName, FileMode.Create); + encoder.Save(fs); + } + + #endregion } }