线灰度和辅助线粗细根据图像分辨率自适应,图像切换时自动重绘

This commit is contained in:
李伟
2026-05-26 11:22:28 +08:00
parent 7c06cd2def
commit 77f6a32eda
3 changed files with 77 additions and 6 deletions
@@ -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);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

@@ -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<WhiteBackgroundDetectionEvent>().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()}");
}
/// <summary>
/// 图像变化时重绘线灰度(移除旧元素,重新创建)
/// </summary>
private void RedrawLineProfile()
{
var canvas = FindChildByName<System.Windows.Controls.Canvas>(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)