diff --git a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs index 1ddedc0..e046738 100644 --- a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs +++ b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs @@ -444,8 +444,9 @@ namespace XP.ImageProcessing.RoiControl.Controls double w = CanvasWidth, h = CanvasHeight; if (w <= 0 || h <= 0) return; - _crosshairH = new Line { X1 = 0, Y1 = h / 2, X2 = w, Y2 = h / 2, Stroke = Brushes.Red, StrokeThickness = 1, Opacity = 0.7, IsHitTestVisible = false }; - _crosshairV = new Line { X1 = w / 2, Y1 = 0, X2 = w / 2, Y2 = h, Stroke = Brushes.Red, StrokeThickness = 1, Opacity = 0.7, IsHitTestVisible = false }; + double thickness = Math.Max(1, Math.Round(Math.Max(w, h) / 1000.0)); + _crosshairH = new Line { X1 = 0, Y1 = h / 2, X2 = w, Y2 = h / 2, Stroke = Brushes.Red, StrokeThickness = thickness, Opacity = 0.7, IsHitTestVisible = false }; + _crosshairV = new Line { X1 = w / 2, Y1 = 0, X2 = w / 2, Y2 = h, Stroke = Brushes.Red, StrokeThickness = thickness, Opacity = 0.7, IsHitTestVisible = false }; mainCanvas.Children.Add(_crosshairH); mainCanvas.Children.Add(_crosshairV); } diff --git a/XplorePlane/Assets/Icons/QFN.png b/XplorePlane/Assets/Icons/QFN.png new file mode 100644 index 0000000..b2dd0e3 Binary files /dev/null and b/XplorePlane/Assets/Icons/QFN.png differ diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs index f0957da..80fb852 100644 --- a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs +++ b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs @@ -187,6 +187,14 @@ namespace XplorePlane.Views ToggleLineProfile(); }, Prism.Events.ThreadOption.UIThread); + // 图像变化时重绘线灰度 + var canvasWidthDesc = System.ComponentModel.DependencyPropertyDescriptor.FromProperty( + PolygonRoiCanvas.CanvasWidthProperty, typeof(PolygonRoiCanvas)); + canvasWidthDesc?.AddValueChanged(RoiCanvas, (s, e) => + { + if (_lineProfileEnabled) RedrawLineProfile(); + }); + // 白底检测:进入ROI绘制模式 ea2?.GetEvent().Subscribe(() => { @@ -256,8 +264,12 @@ namespace XplorePlane.Views // 参考线默认在图像中间 _profileLineY = RoiCanvas.CanvasHeight / 2; + // 根据图像分辨率自适应线条粗细 + double maxDim = Math.Max(RoiCanvas.CanvasWidth, RoiCanvas.CanvasHeight); + double lineThickness = Math.Max(1, Math.Round(maxDim / 1000.0)); + // 创建参考线(红色水平线,可拖动) - // 用透明粗线作为命中区域,叠加1px红线显示 + // 用透明粗线作为命中区域,叠加红线显示 _profileRefLine = new System.Windows.Shapes.Line { X1 = 0, @@ -265,7 +277,7 @@ namespace XplorePlane.Views X2 = RoiCanvas.CanvasWidth, Y2 = _profileLineY, Stroke = System.Windows.Media.Brushes.Transparent, - StrokeThickness = 7, // 上下3px命中区域 + StrokeThickness = lineThickness + 6, // 上下命中区域 IsHitTestVisible = true, Cursor = System.Windows.Input.Cursors.SizeNS }; @@ -276,7 +288,7 @@ namespace XplorePlane.Views X2 = RoiCanvas.CanvasWidth, Y2 = _profileLineY, Stroke = System.Windows.Media.Brushes.Red, - StrokeThickness = 1, + StrokeThickness = lineThickness, IsHitTestVisible = false }; _profileRefLine.MouseLeftButtonDown += ProfileLine_MouseDown; @@ -289,7 +301,7 @@ namespace XplorePlane.Views _profileCurve = new System.Windows.Shapes.Polyline { Stroke = System.Windows.Media.Brushes.Red, - StrokeThickness = 1, + StrokeThickness = lineThickness, IsHitTestVisible = false }; canvas.Children.Add(_profileCurve); @@ -393,6 +405,64 @@ namespace XplorePlane.Views SetStatus($"行灰度分布 | Y={row} | 均值={rowPixels.Select(b => (double)b).Average():F1} | 最大={rowPixels.Max()} | 最小={rowPixels.Min()}"); } + /// + /// 图像变化时重绘线灰度(移除旧元素,重新创建) + /// + private void RedrawLineProfile() + { + var canvas = FindChildByName(RoiCanvas, "mainCanvas"); + if (canvas == null) return; + + // 移除旧元素 + if (_profileRefLine != null) { canvas.Children.Remove(_profileRefLine); _profileRefLine = null; } + if (_profileRefLineVisible != null) { canvas.Children.Remove(_profileRefLineVisible); _profileRefLineVisible = null; } + if (_profileCurve != null) { canvas.Children.Remove(_profileCurve); _profileCurve = null; } + + // 重新计算参考线位置(保持相对比例或重置到中间) + _profileLineY = RoiCanvas.CanvasHeight / 2; + + // 根据新图像分辨率自适应线条粗细 + double maxDim = Math.Max(RoiCanvas.CanvasWidth, RoiCanvas.CanvasHeight); + double lineThickness = Math.Max(1, Math.Round(maxDim / 1000.0)); + + _profileRefLine = new System.Windows.Shapes.Line + { + X1 = 0, + Y1 = _profileLineY, + X2 = RoiCanvas.CanvasWidth, + Y2 = _profileLineY, + Stroke = System.Windows.Media.Brushes.Transparent, + StrokeThickness = lineThickness + 6, + IsHitTestVisible = true, + Cursor = System.Windows.Input.Cursors.SizeNS + }; + _profileRefLineVisible = new System.Windows.Shapes.Line + { + X1 = 0, + Y1 = _profileLineY, + X2 = RoiCanvas.CanvasWidth, + Y2 = _profileLineY, + Stroke = System.Windows.Media.Brushes.Red, + StrokeThickness = lineThickness, + IsHitTestVisible = false + }; + _profileRefLine.MouseLeftButtonDown += ProfileLine_MouseDown; + _profileRefLine.MouseMove += ProfileLine_MouseMove; + _profileRefLine.MouseLeftButtonUp += ProfileLine_MouseUp; + canvas.Children.Add(_profileRefLineVisible); + canvas.Children.Add(_profileRefLine); + + _profileCurve = new System.Windows.Shapes.Polyline + { + Stroke = System.Windows.Media.Brushes.Red, + StrokeThickness = lineThickness, + IsHitTestVisible = false + }; + canvas.Children.Add(_profileCurve); + + UpdateLineProfile(); + } + #endregion private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)