using System.Drawing; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using XP.Camera.Calibration.ViewModels; using WpfBrushes = System.Windows.Media.Brushes; using WpfColor = System.Windows.Media.Color; namespace XP.Camera.Calibration.Controls; public partial class CalibrationControl : UserControl { private CalibrationViewModel? _viewModel; public CalibrationControl() { InitializeComponent(); Loaded += CalibrationControl_Loaded; } private void CalibrationControl_Loaded(object sender, RoutedEventArgs e) { if (DataContext is CalibrationViewModel viewModel) { _viewModel = viewModel; _viewModel.ImageLoadedRequested += (s, e) => { imageCanvas.ReferenceImage = _viewModel.ImageSource; imageCanvas.RoiCanvas.Children.Clear(); }; imageCanvas.CanvasRightMouseUp += ImageCanvas_RightMouseUp; imageCanvas.CanvasMouseWheel += ImageCanvas_MouseWheel; } } private void ImageCanvas_MouseWheel(object? sender, MouseWheelEventArgs e) { if (_viewModel?.CurrentImage == null) return; double zoom = e.Delta > 0 ? 1.1 : 0.9; imageCanvas.ZoomScale *= zoom; imageCanvas.ZoomScale = Math.Max(0.1, Math.Min(imageCanvas.ZoomScale, 10)); } private void ImageCanvas_RightMouseUp(object? sender, MouseButtonEventArgs e) { if (_viewModel?.CurrentImage == null) return; var pos = e.GetPosition(imageCanvas.RoiCanvas); float imageX = (float)pos.X; float imageY = (float)pos.Y; if (imageX >= 0 && imageX < _viewModel.CurrentImage.Width && imageY >= 0 && imageY < _viewModel.CurrentImage.Height) { var pixelPoint = new PointF(imageX, imageY); var worldPoint = _viewModel.ConvertPixelToWorld(pixelPoint); _viewModel.StatusText = $"像素坐标: ({imageX:F2}, {imageY:F2})\n世界坐标: ({worldPoint.X:F2}, {worldPoint.Y:F2})"; DrawMarkerOnCanvas(imageX, imageY, worldPoint); } } private void DrawMarkerOnCanvas(float imageX, float imageY, PointF worldPoint) { imageCanvas.RoiCanvas.Children.Clear(); var ellipse = new System.Windows.Shapes.Ellipse { Width = 10, Height = 10, Stroke = WpfBrushes.Red, StrokeThickness = 2, Fill = WpfBrushes.Transparent }; Canvas.SetLeft(ellipse, imageX - 5); Canvas.SetTop(ellipse, imageY - 5); imageCanvas.RoiCanvas.Children.Add(ellipse); var pixelText = new TextBlock { Text = $"P:({imageX:F0},{imageY:F0})", Foreground = WpfBrushes.Red, FontSize = 12, Background = new System.Windows.Media.SolidColorBrush(WpfColor.FromArgb(180, 255, 255, 255)) }; Canvas.SetLeft(pixelText, imageX + 10); Canvas.SetTop(pixelText, imageY - 20); imageCanvas.RoiCanvas.Children.Add(pixelText); if (_viewModel?.ShowWorldCoordinates == true) { var worldText = new TextBlock { Text = $"W:({worldPoint.X:F2},{worldPoint.Y:F2})", Foreground = WpfBrushes.Blue, FontSize = 12, Background = new System.Windows.Media.SolidColorBrush(WpfColor.FromArgb(180, 255, 255, 255)) }; Canvas.SetLeft(worldText, imageX + 10); Canvas.SetTop(worldText, imageY + 5); imageCanvas.RoiCanvas.Children.Add(worldText); } } }