测量工具组线宽根据图像分辨率自适应

This commit is contained in:
李伟
2026-05-26 11:35:25 +08:00
parent 77f6a32eda
commit 82b7c32147
@@ -461,6 +461,16 @@ namespace XP.ImageProcessing.RoiControl.Controls
#region Measurement
/// <summary>
/// 根据画布尺寸计算自适应线宽
/// </summary>
private double GetAdaptiveThickness(double baseThickness = 1.0)
{
double maxDim = Math.Max(CanvasWidth, CanvasHeight);
double scale = Math.Max(1, Math.Round(maxDim / 1000.0));
return baseThickness * scale;
}
public static readonly DependencyProperty CurrentMeasureModeProperty =
DependencyProperty.Register(nameof(CurrentMeasureMode), typeof(Models.MeasureMode), typeof(PolygonRoiCanvas),
new PropertyMetadata(Models.MeasureMode.None, OnMeasureModeChanged));
@@ -759,12 +769,12 @@ namespace XP.ImageProcessing.RoiControl.Controls
private Models.MeasureGroup CreatePPGroup(Point p1, Point p2)
{
var g = new Models.MeasureGroup { P1 = p1, P2 = p2 };
g.Line = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false };
g.Line = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false };
g.Label = new TextBlock { Foreground = Brushes.Yellow, FontSize = 13, FontWeight = FontWeights.Bold, IsHitTestVisible = false };
// 使用垂直线段代替圆点
g.PerpLine1 = new Line { Stroke = Brushes.Yellow, StrokeThickness = 1, IsHitTestVisible = true, Cursor = Cursors.Hand };
g.PerpLine2 = new Line { Stroke = Brushes.Yellow, StrokeThickness = 1, IsHitTestVisible = true, Cursor = Cursors.Hand };
g.PerpLine1 = new Line { Stroke = Brushes.Yellow, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = true, Cursor = Cursors.Hand };
g.PerpLine2 = new Line { Stroke = Brushes.Yellow, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = true, Cursor = Cursors.Hand };
// 保留圆点以兼容拖拽逻辑(但设为不可见)
g.Dot1 = CreateMDot(Brushes.Red);
@@ -866,7 +876,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
_ptlTempDot2 = CreateMDot(Brushes.Lime);
_measureOverlay.Children.Add(_ptlTempDot2);
SetDotPos(_ptlTempDot2, pos);
_ptlTempLine = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false,
_ptlTempLine = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false,
X1 = _ptlTempL1.Value.X, Y1 = _ptlTempL1.Value.Y, X2 = pos.X, Y2 = pos.Y };
_measureOverlay.Children.Add(_ptlTempLine);
RaiseMeasureStatusChanged($"点线距 - 直线已定义,请点击测量点");
@@ -892,10 +902,10 @@ namespace XP.ImageProcessing.RoiControl.Controls
private Models.PointToLineGroup CreatePTLGroup(Point l1, Point l2, Point p)
{
var g = new Models.PointToLineGroup { L1 = l1, L2 = l2, P = p };
g.MainLine = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false };
g.ExtLine = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false,
g.MainLine = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false };
g.ExtLine = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false,
StrokeDashArray = new DoubleCollection { 4, 2 }, Visibility = Visibility.Collapsed };
g.PerpLine = new Line { Stroke = Brushes.Yellow, StrokeThickness = 1, IsHitTestVisible = false,
g.PerpLine = new Line { Stroke = Brushes.Yellow, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false,
StrokeDashArray = new DoubleCollection { 4, 2 } };
g.FootDot = new Ellipse { Width = 2, Height = 2, Fill = Brushes.Cyan, Stroke = Brushes.White, StrokeThickness = 0.5, IsHitTestVisible = false };
g.Label = new TextBlock { Foreground = Brushes.Yellow, FontSize = 13, FontWeight = FontWeights.Bold, IsHitTestVisible = false };
@@ -929,7 +939,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
_elfTempLine = new Line
{
Stroke = Brushes.Cyan,
StrokeThickness = 1,
StrokeThickness = GetAdaptiveThickness(),
StrokeDashArray = new DoubleCollection { 4, 2 },
IsHitTestVisible = false,
X1 = _elfTempStart.Value.X,
@@ -972,7 +982,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
_angleTempADot = CreateMDot(Brushes.Orange);
_measureOverlay.Children.Add(_angleTempADot);
SetDotPos(_angleTempADot, pos);
_angleTempLineA = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false,
_angleTempLineA = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false,
X1 = _angleTempV.Value.X, Y1 = _angleTempV.Value.Y, X2 = pos.X, Y2 = pos.Y };
_measureOverlay.Children.Add(_angleTempLineA);
RaiseMeasureStatusChanged($"角度测量 - 射线A已定义,请点击射线端点B");
@@ -998,9 +1008,9 @@ namespace XP.ImageProcessing.RoiControl.Controls
private Models.AngleGroup CreateAngleGroup(Point v, Point a, Point b)
{
var g = new Models.AngleGroup { V = v, A = a, B = b };
g.LineA = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false };
g.LineB = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false };
g.Arc = new Path { Stroke = Brushes.Yellow, StrokeThickness = 1.5, IsHitTestVisible = false };
g.LineA = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false };
g.LineB = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false };
g.Arc = new Path { Stroke = Brushes.Yellow, StrokeThickness = GetAdaptiveThickness(1.5), IsHitTestVisible = false };
g.Label = new TextBlock { Foreground = Brushes.Yellow, FontSize = 13, FontWeight = FontWeights.Bold, IsHitTestVisible = false };
g.DotV = CreateMDot(Brushes.Red);
g.DotA = CreateMDot(Brushes.Orange);
@@ -1041,8 +1051,8 @@ namespace XP.ImageProcessing.RoiControl.Controls
g.PathE3 = CreateEllipsePath(Brushes.Yellow, true);
g.PathE4 = CreateEllipsePath(Brushes.Lime, false);
g.FullLine = new Line { Stroke = Brushes.Red, StrokeThickness = 1, IsHitTestVisible = false };
g.FillLine = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false };
g.FullLine = new Line { Stroke = Brushes.Red, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false };
g.FillLine = new Line { Stroke = Brushes.Lime, StrokeThickness = GetAdaptiveThickness(), IsHitTestVisible = false };
g.Label = new TextBlock { FontSize = 13, FontWeight = FontWeights.Bold, Cursor = Cursors.Hand };
g.Label.SetValue(ContextMenuService.IsEnabledProperty, false);
@@ -1079,9 +1089,9 @@ namespace XP.ImageProcessing.RoiControl.Controls
return h;
}
private static Path CreateEllipsePath(Brush stroke, bool dashed)
private Path CreateEllipsePath(Brush stroke, bool dashed)
{
var p = new Path { Stroke = stroke, StrokeThickness = 1.5, IsHitTestVisible = false };
var p = new Path { Stroke = stroke, StrokeThickness = GetAdaptiveThickness(1.5), IsHitTestVisible = false };
if (dashed) p.StrokeDashArray = new DoubleCollection { 4, 2 };
return p;
}
@@ -1165,7 +1175,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
c.Shape = new Ellipse
{
Stroke = isBall ? Brushes.Lime : Brushes.Orange,
StrokeThickness = isBall ? 2 : 1.5,
StrokeThickness = isBall ? GetAdaptiveThickness(2) : GetAdaptiveThickness(1.5),
Fill = Brushes.Transparent,
IsHitTestVisible = false
};
@@ -1553,7 +1563,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
_bubbleRoiRect = new Rectangle
{
Stroke = Brushes.Red,
StrokeThickness = 1,
StrokeThickness = GetAdaptiveThickness(),
Fill = Brushes.Transparent,
Visibility = Visibility.Collapsed,
IsHitTestVisible = false
@@ -1610,7 +1620,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
_bubbleCircleShape = new Ellipse
{
Stroke = Brushes.Red,
StrokeThickness = 1,
StrokeThickness = GetAdaptiveThickness(),
Fill = Brushes.Transparent,
Visibility = Visibility.Collapsed,
IsHitTestVisible = false
@@ -1639,7 +1649,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
_bubblePolyShape = new Polygon
{
Stroke = Brushes.Red,
StrokeThickness = 1,
StrokeThickness = GetAdaptiveThickness(),
Fill = Brushes.Transparent,
IsHitTestVisible = false
};