diff --git a/XP.Camera/Calibration/Controls/CalibrationControl.xaml b/XP.Camera/Calibration/Controls/CalibrationControl.xaml
index a7bc653..7803ebf 100644
--- a/XP.Camera/Calibration/Controls/CalibrationControl.xaml
+++ b/XP.Camera/Calibration/Controls/CalibrationControl.xaml
@@ -3,7 +3,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:cal="clr-namespace:XP.Camera.Calibration"
xmlns:controls="clr-namespace:XP.Camera.Calibration.Controls"
mc:Ignorable="d"
@@ -20,9 +19,9 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XplorePlane/Views/ImageProcessing/BgaDetectionPanel.xaml.cs b/XplorePlane/Views/ImageProcessing/BgaDetectionPanel.xaml.cs
new file mode 100644
index 0000000..5eb0174
--- /dev/null
+++ b/XplorePlane/Views/ImageProcessing/BgaDetectionPanel.xaml.cs
@@ -0,0 +1,57 @@
+using System.Windows;
+using Prism.Ioc;
+using XP.ImageProcessing.RoiControl.Controls;
+using XplorePlane.Services.MainViewport;
+using XplorePlane.ViewModels.ImageProcessing;
+
+namespace XplorePlane.Views.ImageProcessing
+{
+ public partial class BgaDetectionPanel : Window
+ {
+ public BgaDetectionPanel()
+ {
+ InitializeComponent();
+ var viewportService = ContainerLocator.Current?.Resolve();
+ DataContext = new BgaDetectionViewModel(viewportService);
+
+ Loaded += (s, e) =>
+ {
+ // 获取主界面的 RoiCanvas 传给 ViewModel
+ var mainWin = Owner as MainWindow;
+ if (mainWin != null)
+ {
+ var canvas = FindChild(mainWin);
+ if (DataContext is BgaDetectionViewModel vm)
+ vm.SetCanvas(canvas);
+ }
+ };
+
+ Closed += (s, e) =>
+ {
+ if (DataContext is BgaDetectionViewModel vm)
+ {
+ // 恢复右键菜单,但保留 ROI
+ vm.RestoreContextMenu();
+ }
+ };
+ }
+
+ private void Close_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private static T FindChild(DependencyObject parent) where T : DependencyObject
+ {
+ int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(parent);
+ for (int i = 0; i < count; i++)
+ {
+ var child = System.Windows.Media.VisualTreeHelper.GetChild(parent, i);
+ if (child is T t) return t;
+ var result = FindChild(child);
+ if (result != null) return result;
+ }
+ return null;
+ }
+ }
+}
diff --git a/XplorePlane/Views/ImageProcessing/BgaMeasurePanel.xaml b/XplorePlane/Views/ImageProcessing/BgaMeasurePanel.xaml
index 6467a2e..87aad82 100644
--- a/XplorePlane/Views/ImageProcessing/BgaMeasurePanel.xaml
+++ b/XplorePlane/Views/ImageProcessing/BgaMeasurePanel.xaml
@@ -3,72 +3,94 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BGA空隙测量"
- Width="240" Height="260"
+ Width="280" Height="280"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
- Topmost="True"
- ShowInTaskbar="False">
+ Topmost="True" ShowInTaskbar="False"
+ Background="#F5F5F5" FontFamily="Microsoft YaHei UI">
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
+
\ No newline at end of file
diff --git a/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml b/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml
index 46f1700..e4fc177 100644
--- a/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml
+++ b/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml
@@ -3,92 +3,116 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="气泡测量工具"
- Width="260" Height="340"
+ Width="340" Height="380"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
- Topmost="True"
- ShowInTaskbar="False">
+ Topmost="True" ShowInTaskbar="False"
+ Background="#F5F5F5" FontFamily="Microsoft YaHei UI">
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml.cs b/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml.cs
index 58ba847..99fa7aa 100644
--- a/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml.cs
+++ b/XplorePlane/Views/ImageProcessing/BubbleMeasurePanel.xaml.cs
@@ -48,6 +48,20 @@ namespace XplorePlane.Views.ImageProcessing
_canvas?.SetBubbleBrushSize((int)SliderBrushSize.Value);
};
+ // VoidLimit 同步
+ TbVoidLimit.TextChanged += (s, ev) =>
+ {
+ if (double.TryParse(TbVoidLimit.Text, out double val))
+ _canvas?.SetBubbleVoidLimit(System.Math.Clamp(val, 0, 100));
+ };
+
+ // 初始同步:确保面板默认值推送到 canvas
+ _canvas?.SetBubbleTool(PolygonRoiCanvas.BubbleSubTool.Roi);
+ _canvas?.SetBubbleThreshold((int)SliderThreshold.Value);
+ _canvas?.SetBubbleBrushSize((int)SliderBrushSize.Value);
+ if (double.TryParse(TbVoidLimit.Text, out double initLimit))
+ _canvas?.SetBubbleVoidLimit(System.Math.Clamp(initLimit, 0, 100));
+
// 监听 canvas 的工具切换事件(ROI 画完后自动切换时同步面板)
if (_canvas != null)
{
diff --git a/XplorePlane/Views/HalfValueConverter.cs b/XplorePlane/Views/ImageProcessing/HalfValueConverter.cs
similarity index 100%
rename from XplorePlane/Views/HalfValueConverter.cs
rename to XplorePlane/Views/ImageProcessing/HalfValueConverter.cs
diff --git a/XplorePlane/Views/ImageProcessing/VoidDetectionPanel.xaml b/XplorePlane/Views/ImageProcessing/VoidDetectionPanel.xaml
new file mode 100644
index 0000000..71a9587
--- /dev/null
+++ b/XplorePlane/Views/ImageProcessing/VoidDetectionPanel.xaml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XplorePlane/Views/ImageProcessing/VoidDetectionPanel.xaml.cs b/XplorePlane/Views/ImageProcessing/VoidDetectionPanel.xaml.cs
new file mode 100644
index 0000000..2f9e2b5
--- /dev/null
+++ b/XplorePlane/Views/ImageProcessing/VoidDetectionPanel.xaml.cs
@@ -0,0 +1,50 @@
+using System.Windows;
+using Prism.Ioc;
+using XP.ImageProcessing.RoiControl.Controls;
+using XplorePlane.Services.MainViewport;
+using XplorePlane.ViewModels.ImageProcessing;
+
+namespace XplorePlane.Views.ImageProcessing
+{
+ public partial class VoidDetectionPanel : Window
+ {
+ public VoidDetectionPanel()
+ {
+ InitializeComponent();
+ var viewportService = ContainerLocator.Current?.Resolve();
+ DataContext = new VoidDetectionViewModel(viewportService);
+
+ Loaded += (s, e) =>
+ {
+ var mainWin = Owner as MainWindow;
+ if (mainWin != null)
+ {
+ var canvas = FindChild(mainWin);
+ if (DataContext is VoidDetectionViewModel vm)
+ vm.SetCanvas(canvas);
+ }
+ };
+
+ Closed += (s, e) =>
+ {
+ if (DataContext is VoidDetectionViewModel vm)
+ vm.RestoreContextMenu();
+ };
+ }
+
+ private void Close_Click(object sender, RoutedEventArgs e) => Close();
+
+ private static T FindChild(DependencyObject parent) where T : DependencyObject
+ {
+ int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(parent);
+ for (int i = 0; i < count; i++)
+ {
+ var child = System.Windows.Media.VisualTreeHelper.GetChild(parent, i);
+ if (child is T t) return t;
+ var result = FindChild(child);
+ if (result != null) return result;
+ }
+ return null;
+ }
+ }
+}
diff --git a/XplorePlane/Views/Main/MainWindow.xaml b/XplorePlane/Views/Main/MainWindow.xaml
index 4de574a..ea42682 100644
--- a/XplorePlane/Views/Main/MainWindow.xaml
+++ b/XplorePlane/Views/Main/MainWindow.xaml
@@ -195,8 +195,6 @@
-
-
@@ -209,14 +207,14 @@
telerik:ScreenTip.Title="点点距测量"
Command="{Binding PointDistanceMeasureCommand}"
Size="Medium"
- SmallImage="/Assets/Icons/crosshair.png"
+ SmallImage="/Assets/Icons/ptop.png"
Text="点点距测量" />
@@ -227,14 +225,14 @@
telerik:ScreenTip.Title="角度测量"
Command="{Binding AngleMeasureCommand}"
Size="Medium"
- SmallImage="/Assets/Icons/dynamic-range.png"
+ SmallImage="/Assets/Icons/angle.png"
Text="角度测量" />
@@ -367,19 +365,17 @@
@@ -405,7 +401,6 @@
Size="Large"
SmallImage="/Assets/Icons/spiral.png" />
-
@@ -520,8 +515,7 @@
-
-
+
+
@@ -621,4 +616,4 @@
-
+
\ No newline at end of file
diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml b/XplorePlane/Views/Main/ViewportPanelView.xaml
index 10bc297..195d669 100644
--- a/XplorePlane/Views/Main/ViewportPanelView.xaml
+++ b/XplorePlane/Views/Main/ViewportPanelView.xaml
@@ -33,18 +33,6 @@
x:Name="RoiCanvas"
Background="White"
ImageSource="{Binding ImageSource}">
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs
index 743a755..c8ced63 100644
--- a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs
+++ b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs
@@ -31,6 +31,32 @@ namespace XplorePlane.Views
InitializeComponent();
DataContextChanged += OnDataContextChanged;
+ // 动态创建右键菜单,支持条件性阻止弹出
+ var menu = new System.Windows.Controls.ContextMenu();
+ menu.Items.Add(new System.Windows.Controls.MenuItem { Header = "放大" });
+ menu.Items.Add(new System.Windows.Controls.MenuItem { Header = "缩小" });
+ menu.Items.Add(new System.Windows.Controls.MenuItem { Header = "适应窗口" });
+ menu.Items.Add(new System.Windows.Controls.Separator());
+ menu.Items.Add(new System.Windows.Controls.MenuItem { Header = "保存原始图像" });
+ menu.Items.Add(new System.Windows.Controls.MenuItem { Header = "保存结果图像" });
+ menu.Items.Add(new System.Windows.Controls.Separator());
+ menu.Items.Add(new System.Windows.Controls.MenuItem { Header = "清除所有测量" });
+ ((System.Windows.Controls.MenuItem)menu.Items[0]).Click += ZoomIn_Click;
+ ((System.Windows.Controls.MenuItem)menu.Items[1]).Click += ZoomOut_Click;
+ ((System.Windows.Controls.MenuItem)menu.Items[2]).Click += ResetView_Click;
+ ((System.Windows.Controls.MenuItem)menu.Items[4]).Click += SaveOriginalImage_Click;
+ ((System.Windows.Controls.MenuItem)menu.Items[5]).Click += SaveResultImage_Click;
+ ((System.Windows.Controls.MenuItem)menu.Items[7]).Click += ClearAllMeasurements_Click;
+ RoiCanvas.ContextMenu = menu;
+ RoiCanvas.ContextMenuOpening += (s, e) =>
+ {
+ if (RoiCanvas.SuppressContextMenu)
+ {
+ RoiCanvas.SuppressContextMenu = false;
+ e.Handled = true;
+ }
+ };
+
// 测量事件 → 更新主界面状态栏
RoiCanvas.MeasureCompleted += (s, e) =>
{
@@ -111,6 +137,8 @@ namespace XplorePlane.Views
private void ClearAllMeasurements_Click(object sender, RoutedEventArgs e)
{
RoiCanvas.ClearMeasurements();
+ RoiCanvas.ROIItems?.Clear();
+ RoiCanvas.SelectedROI = null;
if (DataContext is ViewportPanelViewModel vm)
vm.ResetMeasurementState();
SetStatus("已清除所有测量");
diff --git a/XplorePlane/Views/Setting/CameraSettingsWindow.xaml b/XplorePlane/Views/Setting/CameraSettingsWindow.xaml
index 413c33d..a0e9ddc 100644
--- a/XplorePlane/Views/Setting/CameraSettingsWindow.xaml
+++ b/XplorePlane/Views/Setting/CameraSettingsWindow.xaml
@@ -2,56 +2,149 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="相机参数设置"
- Width="320" Height="420"
+ Width="340" Height="440"
WindowStartupLocation="CenterOwner"
- ResizeMode="NoResize"
- ShowInTaskbar="False">
-
+ ResizeMode="NoResize" ShowInTaskbar="False"
+ Background="#F5F5F5" FontFamily="Microsoft YaHei UI">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/XplorePlane/Views/Setting/CameraSettingsWindow.xaml.cs b/XplorePlane/Views/Setting/CameraSettingsWindow.xaml.cs
index e9f43f9..338c524 100644
--- a/XplorePlane/Views/Setting/CameraSettingsWindow.xaml.cs
+++ b/XplorePlane/Views/Setting/CameraSettingsWindow.xaml.cs
@@ -1,4 +1,5 @@
using System.Windows;
+using System.Windows.Input;
namespace XplorePlane.Views
{
@@ -9,5 +10,24 @@ namespace XplorePlane.Views
InitializeComponent();
DataContext = viewModel;
}
+
+ private void ApplyAll_Click(object sender, RoutedEventArgs e)
+ {
+ var dc = DataContext;
+ if (dc == null) return;
+ var type = dc.GetType();
+ ExecuteCommand(type, dc, "ApplyExposureCommand");
+ ExecuteCommand(type, dc, "ApplyGainCommand");
+ ExecuteCommand(type, dc, "ApplyWidthCommand");
+ ExecuteCommand(type, dc, "ApplyHeightCommand");
+ ExecuteCommand(type, dc, "ApplyPixelFormatCommand");
+ }
+
+ private static void ExecuteCommand(System.Type type, object dc, string cmdName)
+ {
+ var prop = type.GetProperty(cmdName);
+ if (prop?.GetValue(dc) is ICommand cmd && cmd.CanExecute(null))
+ cmd.Execute(null);
+ }
}
-}
\ No newline at end of file
+}