using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace MeterVision.Mark { /// /// UCMark.xaml 的交互逻辑 /// public partial class UCMark : UserControl { //当前的放大倍率 //private double _sacle_value = 1.5f; //标注的类型: 4:表盘; 3:数字域; 2:首位指针; 0:未选中 private int _mark_type = 0; //是否已加载图片 //private bool _loadedImage = false; private MarkManager _markManager; private int _meterType = -1; public int MeterType { private get => _meterType; set { //if(_meterType != value) { _meterType = value; SetFeatureRegion(_meterType); } } } public event Action MeterRegion_MarkFinished; public event Action FeatureRegion_MarkFinished; BitmapImage bitmap; public UCMark() { InitializeComponent(); _mark_type = 0; _markManager = new MarkManager(drawingCanvas); _markManager.MarkError += _markManager_MarkError; _markManager.FinishMark += _markManager_FinishMark; //初始化一些控件的默认显示值 txtCurPoint.Text = ""; this.Loaded += UCMark_Loaded; } private void UCMark_Loaded(object sender, RoutedEventArgs e) { //throw new NotImplementedException(); //ChangeScale(); } private void PnlCanvas_SizeChanged(object sender, SizeChangedEventArgs e) { ChangeScale(); if (_markManager != null) { _markManager.ClearMark(); } } public void SetImagePath(string imgPath) { //MeterType = meterType; //加载照片 LoadImage(imgPath); //设置放大倍率 //_sacle_value = 1.92f; //SetScaleTrnsform(_sacle_value); } //private void SetScaleTrnsform(double scale) //{ // scaleTransform.ScaleX = scale; // scaleTransform.ScaleY = scale; // _markManager.ClearMark(); //} private void LoadImage(string filePath) { // 创建一个BitmapImage对象,并加载图片 bitmap = new BitmapImage(new Uri(filePath)); if (bitmap.Width != 320 || bitmap.Height != 240) { MessageBox.Show(Application.Current.MainWindow, "图片尺寸必须为320*240!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } imgControl.Source = bitmap; // 将图片显示到Image控件中 drawingCanvas.Width = bitmap.PixelWidth; drawingCanvas.Height = bitmap.PixelHeight; _markManager.InitMark(); } private void ChangeScale() { // 获取图片原始尺寸 double imageWidth = bitmap.PixelWidth; double imageHeight = bitmap.PixelHeight; // 获取pnlCanvas的实际可用区域(考虑Margin和Padding) double containerWidth = pnlCanvas.ActualWidth - pnlCanvas.Padding.Left - pnlCanvas.Padding.Right; double containerHeight = pnlCanvas.ActualHeight - pnlCanvas.Padding.Top - pnlCanvas.Padding.Bottom; // 计算缩放比例,留5%边距 double scaleX = (containerWidth * 0.95) / imageWidth; double scaleY = (containerHeight * 0.95) / imageHeight; double scale = Math.Min(scaleX, scaleY); // 应用缩放 scaleTransform.ScaleX = scale; scaleTransform.ScaleY = scale; // 计算图片缩放后的尺寸 double scaledWidth = imageWidth * scale; double scaledHeight = imageHeight * scale; // 将图片居中于Canvas //Canvas.SetLeft(imgControl, (containerWidth - scaledWidth) / 2); //Canvas.SetTop(imgControl, (containerHeight - scaledHeight) / 2); // 关键步骤:强制Canvas与Image的渲染区域一致 drawingCanvas.Width = scaledWidth; //containerWidth; // 使Canvas宽度与Border可用区域一致 drawingCanvas.Height = scaledHeight; //containerHeight; // 使Canvas高度与Border可用区域一致 } private void _markManager_FinishMark(int pointCount, List points, int angle) { double scaleX = scaleTransform.ScaleX; double scaleY = scaleTransform.ScaleY; string regions = ""; if (_mark_type == 4) { //表盘标注完成(获取到2组坐标) Point point1 = points[0]; Point point2 = points[1]; int xMin = (int)(point1.X / scaleX); int yMin = (int)(point1.Y / scaleY); int xMax = (int)(point2.X / scaleX); int yMax = (int)(point2.Y / scaleY); regions = $"{xMin},{yMin} {xMax},{yMax}"; MeterRegion_MarkFinished?.Invoke(regions,MeterType); } else if (_mark_type == 3) { //数字区域标注完成 regions = $"" + $"{(int)(points[0].X / scaleX)}," + $"{(int)(points[0].Y / scaleY)} " + $"{(int)(points[1].X / scaleX)}," + $"{(int)(points[1].Y / scaleY)} " + $"{(int)(points[2].X / scaleX)}," + $"{(int)(points[2].Y / scaleY)} " + $"{(int)(points[3].X / scaleX)}," + $"{(int)(points[3].Y / scaleY)}"; FeatureRegion_MarkFinished?.Invoke(regions,MeterType); } else if (_mark_type == 2) { //指针首位标注完成 regions = $"" + $"{(int)(points[0].X / scaleX)}," + $"{(int)(points[0].Y / scaleY)} " + $"{(int)(points[1].X / scaleX)}," + $"{(int)(points[1].Y / scaleY)}"; FeatureRegion_MarkFinished?.Invoke(regions, MeterType); } } private void _markManager_MarkError(string message) { MessageBox.Show(message); } private void SetFeatureRegion(int meterType) { if(meterType == 1 || meterType == 3) { pnlMarkFunc.Visibility = Visibility.Visible; btnFeatureRegion.Visibility = txtFeatureRegion.Visibility = Visibility.Visible; btnFeatureRegion.Content = "标注数据域(4点)"; } else if(meterType == 2) { pnlMarkFunc.Visibility = Visibility.Visible; btnFeatureRegion.Visibility = txtFeatureRegion.Visibility = Visibility.Visible; btnFeatureRegion.Content = "标注首位指针(2点)"; } else { pnlMarkFunc.Visibility = Visibility.Hidden; //btnFeatureRegion.Visibility = txtFeatureRegion.Visibility = Visibility.Collapsed; } } private void SetBtnMark(int mark_type) { btnMeterRegion.Foreground = btnFeatureRegion.Foreground = Brushes.Black; if(mark_type == 4) { btnMeterRegion.Foreground = Brushes.Red; } else if(mark_type == 2 || mark_type == 3) { btnFeatureRegion.Foreground = Brushes.Red; } } private void BtnMeterRegion_Click(object sender, RoutedEventArgs e) { if (MeterType <= 0) return; if(_mark_type != 4) { _mark_type = 4; _markManager.ReadyMark(_mark_type); } else { _mark_type = 0; _markManager.StopMark(); } SetBtnMark(_mark_type); } private void BtnFeatureRegion_Click(object sender, RoutedEventArgs e) { if(MeterType == 1 || MeterType == 3) { //数字域标注 if(_mark_type != 3) { _mark_type = 3; _markManager.ReadyMark(_mark_type); } else { _mark_type = 0; _markManager.StopMark(); } } else if(MeterType == 2) { //首位指针标注 if(_mark_type != 2) { _mark_type = 2; _markManager.ReadyMark(_mark_type); } else { _mark_type = 2; _markManager.StopMark(); } } SetBtnMark(_mark_type); } private void BtnClearMark_Click(object sender, RoutedEventArgs e) { _markManager.ClearMark(); } private void DrawingCanvas_MouseDown(object sender, MouseButtonEventArgs e) { if (_markManager.IsMarking && _mark_type > 0) { //获取点击位置 Point clickPoint = e.GetPosition(drawingCanvas); _markManager.PointMark(clickPoint); } } private void DrawingCanvas_MouseMove(object sender, MouseEventArgs e) { Point mousePos = e.GetPosition(drawingCanvas); // 将鼠标位置转换为原图的坐标 double originalX = mousePos.X / scaleTransform.ScaleX; double originalY = mousePos.Y / scaleTransform.ScaleY; int mouseX = (int)originalX; int mouseY = (int)originalY; if(_markManager != null && _markManager.PointCount == 3) { _markManager.MouseDrawLine(mousePos); } //this.Title = $"Mouse Position : {mouseX},{mouseY}"; txtCurPoint.Text = $"鼠标坐标: {mouseX},{mouseY}"; } private void DrawingCanvas_MouseUp(object sender, MouseButtonEventArgs e) { } private void DrawingCanvas_MouseEnter(object sender, MouseEventArgs e) { if (_mark_type > 0) { this.Cursor = Cursors.Hand; } else { this.Cursor = Cursors.Arrow; } } private void DrawingCanvas_MouseLeave(object sender, MouseEventArgs e) { txtCurPoint.Text = ""; this.Cursor = Cursors.Arrow; } //----------------------------------------------------------------------- } }