348 lines
9.4 KiB
C#
348 lines
9.4 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using OrpaonVision.SiteApp.Runtime.Services;
|
|
using OrpaonVision.SiteApp.ViewModels;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Media;
|
|
|
|
namespace OrpaonVision.SiteApp;
|
|
|
|
/// <summary>
|
|
/// 优化的主窗口。
|
|
/// </summary>
|
|
public partial class OptimizedMainWindow : Window
|
|
{
|
|
private readonly OptimizedMainWindowViewModel _viewModel;
|
|
private readonly ILogger<OptimizedMainWindow> _logger;
|
|
private System.Windows.Threading.DispatcherTimer? _autoRunTimer;
|
|
|
|
/// <summary>
|
|
/// 构造函数。
|
|
/// </summary>
|
|
public OptimizedMainWindow(OptimizedMainWindowViewModel viewModel, ILogger<OptimizedMainWindow> logger)
|
|
{
|
|
_viewModel = viewModel;
|
|
_logger = logger;
|
|
|
|
InitializeComponent();
|
|
DataContext = _viewModel;
|
|
|
|
Title = "OrpaonVision 运行端 - 实时图像检测";
|
|
|
|
// 初始化自动运行定时器
|
|
InitializeAutoRunTimer();
|
|
|
|
_logger.LogInformation("优化主窗口已初始化");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行一轮检测点击事件。
|
|
/// </summary>
|
|
private void OnRunOneCycleClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.RunOneCycle();
|
|
_logger.LogInformation("手动执行一轮检测完成");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "执行一轮检测失败");
|
|
MessageBox.Show($"执行检测失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 切换下一层点击事件。
|
|
/// </summary>
|
|
private void OnMoveNextLayerClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.MoveToNextLayer();
|
|
_logger.LogInformation("切换到下一层完成");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "切换下一层失败");
|
|
MessageBox.Show($"切换下一层失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 重置运行状态点击事件。
|
|
/// </summary>
|
|
private void OnResetRuntimeClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
// 停止自动运行
|
|
if (_viewModel.IsAutoRunning)
|
|
{
|
|
_viewModel.ToggleAutoRun();
|
|
}
|
|
|
|
_viewModel.ResetRuntime();
|
|
_logger.LogInformation("重置运行状态完成");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "重置运行状态失败");
|
|
MessageBox.Show($"重置状态失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 切换自动运行点击事件。
|
|
/// </summary>
|
|
private void OnToggleAutoRunClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ToggleAutoRun();
|
|
UpdateAutoRunTimer();
|
|
_logger.LogInformation("切换自动运行状态: {IsRunning}", _viewModel.IsAutoRunning);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "切换自动运行失败");
|
|
MessageBox.Show($"切换自动运行失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 保存图像点击事件。
|
|
/// </summary>
|
|
private void OnSaveImageClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.SaveCurrentImage();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "保存图像失败");
|
|
MessageBox.Show($"保存图像失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 无滤镜点击事件。
|
|
/// </summary>
|
|
private void OnFilterNoneClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ApplyImageFilter(ImageFilter.None);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "应用无滤镜失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 灰度滤镜点击事件。
|
|
/// </summary>
|
|
private void OnFilterGrayscaleClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ApplyImageFilter(ImageFilter.Grayscale);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "应用灰度滤镜失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 二值化滤镜点击事件。
|
|
/// </summary>
|
|
private void OnFilterBinaryClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ApplyImageFilter(ImageFilter.Binary);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "应用二值化滤镜失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 边缘检测滤镜点击事件。
|
|
/// </summary>
|
|
private void OnFilterEdgeClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ApplyImageFilter(ImageFilter.EdgeDetection);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "应用边缘检测滤镜失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 模糊滤镜点击事件。
|
|
/// </summary>
|
|
private void OnFilterBlurClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ApplyImageFilter(ImageFilter.Blur);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "应用模糊滤镜失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 锐化滤镜点击事件。
|
|
/// </summary>
|
|
private void OnFilterSharpenClicked(object sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.ApplyImageFilter(ImageFilter.Sharpen);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "应用锐化滤镜失败");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化自动运行定时器。
|
|
/// </summary>
|
|
private void InitializeAutoRunTimer()
|
|
{
|
|
_autoRunTimer = new System.Windows.Threading.DispatcherTimer
|
|
{
|
|
Interval = TimeSpan.FromMilliseconds(1000 / _viewModel.FrameRate)
|
|
};
|
|
_autoRunTimer.Tick += OnAutoRunTimerTick;
|
|
|
|
// 监听帧率变化
|
|
_viewModel.PropertyChanged += (sender, e) =>
|
|
{
|
|
if (e.PropertyName == nameof(_viewModel.FrameRate))
|
|
{
|
|
UpdateAutoRunTimer();
|
|
}
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新自动运行定时器。
|
|
/// </summary>
|
|
private void UpdateAutoRunTimer()
|
|
{
|
|
if (_autoRunTimer == null)
|
|
return;
|
|
|
|
if (_viewModel.IsAutoRunning)
|
|
{
|
|
_autoRunTimer.Interval = TimeSpan.FromMilliseconds(1000 / _viewModel.FrameRate);
|
|
_autoRunTimer.Start();
|
|
}
|
|
else
|
|
{
|
|
_autoRunTimer.Stop();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自动运行定时器触发事件。
|
|
/// </summary>
|
|
private void OnAutoRunTimerTick(object? sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_viewModel.RunOneCycle();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "自动运行检测失败");
|
|
|
|
// 自动运行出错时停止自动运行
|
|
_viewModel.ToggleAutoRun();
|
|
UpdateAutoRunTimer();
|
|
|
|
Dispatcher.Invoke(() =>
|
|
{
|
|
MessageBox.Show($"自动运行出错,已停止: {ex.Message}", "自动运行错误", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
});
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 窗口关闭事件。
|
|
/// </summary>
|
|
protected override void OnClosed(EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
// 停止自动运行
|
|
if (_autoRunTimer != null)
|
|
{
|
|
_autoRunTimer.Stop();
|
|
_autoRunTimer.Tick -= OnAutoRunTimerTick;
|
|
}
|
|
|
|
_logger.LogInformation("优化主窗口已关闭");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "关闭窗口时出错");
|
|
}
|
|
|
|
base.OnClosed(e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 布尔值到自动运行文本转换器。
|
|
/// </summary>
|
|
public class BoolToAutoRunTextConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
|
{
|
|
if (value is bool isRunning)
|
|
{
|
|
return isRunning ? "停止自动运行" : "启动自动运行";
|
|
}
|
|
return "启动自动运行";
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 布尔值到自动运行颜色转换器。
|
|
/// </summary>
|
|
public class BoolToAutoRunColorConverter : IValueConverter
|
|
{
|
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
|
{
|
|
if (value is bool isRunning)
|
|
{
|
|
return isRunning ? Brushes.OrangeRed : Brushes.DarkGreen;
|
|
}
|
|
return Brushes.DarkGreen;
|
|
}
|
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|