From 6b35da4cc0072508c5406bd6f66f2ef3a6481c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=BC=9F?= Date: Thu, 30 Apr 2026 15:51:29 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=A0=8F=E5=8F=B3=E4=B8=8B?= =?UTF-8?q?=E8=A7=92=E6=98=BE=E7=A4=BA=E5=9B=BE=E5=83=8F=E5=83=8F=E7=B4=A0?= =?UTF-8?q?=E5=9D=90=E6=A0=87=E5=92=8C=E7=81=B0=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controls/PolygonRoiCanvas.xaml | 1 + .../Controls/PolygonRoiCanvas.xaml.cs | 48 +++++++++++++++++++ XplorePlane/ViewModels/Main/MainViewModel.cs | 7 +++ XplorePlane/Views/Main/MainWindow.xaml | 2 +- .../Views/Main/ViewportPanelView.xaml.cs | 19 +++++++- 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml index 0546e65..bc732a8 100644 --- a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml +++ b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml @@ -41,6 +41,7 @@ MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseMove="Canvas_MouseMove" + MouseLeave="Canvas_MouseLeave" MouseRightButtonDown="Canvas_MouseRightButtonDown" PreviewMouseRightButtonUp="Canvas_PreviewMouseRightButtonUp"> diff --git a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs index 929433d..85d81fb 100644 --- a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs +++ b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs @@ -299,6 +299,19 @@ namespace XP.ImageProcessing.RoiControl.Controls set => SetValue(ShowCrosshairProperty, value); } + // ── 光标信息(像素坐标 + 灰度值)── + + public static readonly DependencyProperty CursorInfoProperty = + DependencyProperty.Register(nameof(CursorInfo), typeof(string), typeof(PolygonRoiCanvas), + new PropertyMetadata("X: -- Y: -- Gray: --")); + + /// 鼠标在图像上的像素坐标和灰度值,格式: "X: 123 Y: 456 Gray: 128" + public string CursorInfo + { + get => (string)GetValue(CursorInfoProperty); + set => SetValue(CursorInfoProperty, value); + } + private Line _crosshairH, _crosshairV; private static void OnShowCrosshairChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) @@ -1739,6 +1752,38 @@ namespace XP.ImageProcessing.RoiControl.Controls #region Mouse Events + private void UpdateCursorInfo(Point pos) + { + if (ImageSource == null) + { + CursorInfo = "X: -- Y: -- Gray: --"; + return; + } + + int px = (int)pos.X, py = (int)pos.Y; + string grayText = "--"; + + if (ImageSource is BitmapSource bmp && px >= 0 && py >= 0 && px < bmp.PixelWidth && py < bmp.PixelHeight) + { + try + { + var pixel = new byte[4]; + var converted = new FormatConvertedBitmap(bmp, PixelFormats.Bgra32, null, 0); + converted.CopyPixels(new System.Windows.Int32Rect(px, py, 1, 1), pixel, 4, 0); + int gray = (int)(pixel[2] * 0.299 + pixel[1] * 0.587 + pixel[0] * 0.114); + grayText = gray.ToString(); + } + catch { } + } + + CursorInfo = $"X: {px} Y: {py} Gray: {grayText}"; + } + + private void Canvas_MouseLeave(object sender, MouseEventArgs e) + { + CursorInfo = "X: -- Y: -- Gray: --"; + } + private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e) { double oldZoom = ZoomScale; @@ -1881,6 +1926,9 @@ namespace XP.ImageProcessing.RoiControl.Controls lastMousePosition = currentPosition; } } + + // 更新光标信息(像素坐标 + 灰度值) + UpdateCursorInfo(e.GetPosition(mainCanvas)); } private void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) diff --git a/XplorePlane/ViewModels/Main/MainViewModel.cs b/XplorePlane/ViewModels/Main/MainViewModel.cs index 2041f83..20b36e0 100644 --- a/XplorePlane/ViewModels/Main/MainViewModel.cs +++ b/XplorePlane/ViewModels/Main/MainViewModel.cs @@ -265,6 +265,13 @@ namespace XplorePlane.ViewModels public string CncStatusMessage => _cncEditorViewModel.StatusMessage; public bool CncHasExecutionError => _cncEditorViewModel.HasExecutionError; + private string _cursorInfoText = "X: -- Y: -- Gray: --"; + public string CursorInfoText + { + get => _cursorInfoText; + set => SetProperty(ref _cursorInfoText, value); + } + private void ShowWindow(Window window, string name) { window.Owner = Application.Current.MainWindow; diff --git a/XplorePlane/Views/Main/MainWindow.xaml b/XplorePlane/Views/Main/MainWindow.xaml index a460208..cfee2e7 100644 --- a/XplorePlane/Views/Main/MainWindow.xaml +++ b/XplorePlane/Views/Main/MainWindow.xaml @@ -580,7 +580,7 @@ FontFamily="Consolas" FontSize="11" Foreground="White" - Text="x: 0 y: 0" /> + Text="{Binding CursorInfoText}" /> diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs index c8ced63..87b3598 100644 --- a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs +++ b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs @@ -17,13 +17,19 @@ namespace XplorePlane.Views { private MainViewModel _mainVm; - private void SetStatus(string msg) + private MainViewModel GetMainVm() { if (_mainVm == null) { try { _mainVm = ContainerLocator.Current?.Resolve(); } catch { } } - if (_mainVm != null) _mainVm.StatusMessage = msg; + return _mainVm; + } + + private void SetStatus(string msg) + { + var vm = GetMainVm(); + if (vm != null) vm.StatusMessage = msg; } public ViewportPanelView() @@ -113,6 +119,15 @@ namespace XplorePlane.Views }, Prism.Events.ThreadOption.UIThread); } catch { } + + // 光标信息:从 RoiCanvas.CursorInfo 同步到 MainViewModel + var cursorInfoDesc = System.ComponentModel.DependencyPropertyDescriptor.FromProperty( + PolygonRoiCanvas.CursorInfoProperty, typeof(PolygonRoiCanvas)); + cursorInfoDesc?.AddValueChanged(RoiCanvas, (s, e) => + { + var vm = GetMainVm(); + if (vm != null) vm.CursorInfoText = RoiCanvas.CursorInfo; + }); } private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)