From 25d7fc3330947b6f3a10509cea7710d1864efce4 Mon Sep 17 00:00:00 2001 From: wang-yin1 <813860776@qq.com> Date: Wed, 16 Jul 2025 12:20:02 +0800 Subject: [PATCH] 2025-07-16 12:19 --- VisionFrame.Base/Controls/CameraBox.xaml | 25 + VisionFrame.Base/Controls/CameraBox.xaml.cs | 258 ++++++++++ VisionFrame.Base/VisionFrame.Base.csproj | 2 +- VisionFrame/App.xaml | 2 +- VisionFrame/Assets/Styles/ButtonStyles.xaml | 101 ++-- VisionFrame/Assets/Styles/ComboBoxStyles.xaml | 212 ++++---- .../Assets/Styles/TabControlStyles.xaml | 16 +- VisionFrame/Assetss/Fonts/iconfont.ttf | Bin 0 -> 87960 bytes VisionFrame/ViewModels/FlowTabViewModel.cs | 2 +- VisionFrame/ViewModels/MainViewModel.cs | 12 +- VisionFrame/Views/FlowTabView.xaml | 1 + VisionFrame/Views/MainView.xaml | 471 ++++++++++++------ VisionFrame/VisionFrame.csproj | 4 + 13 files changed, 801 insertions(+), 305 deletions(-) create mode 100644 VisionFrame.Base/Controls/CameraBox.xaml create mode 100644 VisionFrame.Base/Controls/CameraBox.xaml.cs create mode 100644 VisionFrame/Assetss/Fonts/iconfont.ttf diff --git a/VisionFrame.Base/Controls/CameraBox.xaml b/VisionFrame.Base/Controls/CameraBox.xaml new file mode 100644 index 0000000..856ced2 --- /dev/null +++ b/VisionFrame.Base/Controls/CameraBox.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/VisionFrame.Base/Controls/CameraBox.xaml.cs b/VisionFrame.Base/Controls/CameraBox.xaml.cs new file mode 100644 index 0000000..1c39810 --- /dev/null +++ b/VisionFrame.Base/Controls/CameraBox.xaml.cs @@ -0,0 +1,258 @@ +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 VisionFrame.Base.Controls +{ + /// + /// 选框事件数据实体 + /// + public class RectEventArgs : RoutedEventArgs + { + public Rect SelectRect { get; } + public double X { get; } + public double Y { get; } + public double Zoom { get; } + public RectEventArgs(RoutedEvent routedEvent, object source, Rect selectRect, double x, double y, double zoom) + : base(routedEvent, source) + { + SelectRect = selectRect; + X = x; + Y = y; + Zoom = zoom; + } + } + /// + /// CameraBox.xaml 的交互逻辑 + /// + public partial class CameraBox : UserControl + { + /// + /// 图像源 + /// + public System.Windows.Media.ImageSource ImageSource + { + get { return (System.Windows.Media.ImageSource)GetValue(ImageSourceProperty); } + set { SetValue(ImageSourceProperty, value); } + } + + public static readonly DependencyProperty ImageSourceProperty = + DependencyProperty.Register("ImageSource", typeof(System.Windows.Media.ImageSource), typeof(CameraBox), new PropertyMetadata(callback)); + + private static void callback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is CameraBox box) + { + var source = e.NewValue as System.Windows.Media.ImageSource; + if (source != null) + { + box.image.Source = source; + } + } + } + + + /// + /// 鼠标是否框选图像 + /// + public bool IsMouseSelect + { + get { return (bool)GetValue(IsMouseSelectProperty); } + set { SetValue(IsMouseSelectProperty, value); } + } + + public static readonly DependencyProperty IsMouseSelectProperty = + DependencyProperty.Register("IsMouseSelect", typeof(bool), typeof(CameraBox), new PropertyMetadata(false)); + + //定义路由事件 + public static readonly RoutedEvent RectChangedEvent + = EventManager.RegisterRoutedEvent("RectChanged", + RoutingStrategy.Bubble, + typeof(RoutedEventHandler), + typeof(CameraBox)); + + /// + /// 选框更改事件 + /// + public event RoutedEventHandler RectChanged + { + add { AddHandler(RectChangedEvent, value); } + remove { RemoveHandler(RectChangedEvent, value); } + } + + protected virtual void OnRectChangedEvent(RectEventArgs e) + { + RaiseEvent(e); + } + + //public void ClearSelectRect() + //{ + // rect.Width = 0; + // rect.Height = 0; + // Canvas.SetLeft(rect, StartPoint.X); + // Canvas.SetTop(rect, StartPoint.Y); + //} + + public TransformGroup TransformGroup { get; private set; } = new TransformGroup(); + private ScaleTransform scaleTransform = new ScaleTransform();//缩放 + private TranslateTransform translateTransform = new TranslateTransform();//平移 + private Point MousePoint = new Point(-1, -1); + private Point StartPoint = new Point(0, 0); + private Point MouseDownPoint = new Point(0, 0);//鼠标按下位置 + private double scale = 1;//默认放大倍数 + private int viewportWidth = 0; + private int viewportHeight = 0; + private int imageBoxWidth = 0; + private int imageBoxHeight = 0; + private bool mousePressed = false; + public double Scale { get; set; } = 1; + /// + /// 鼠标框选区域 + /// + public Rect SelectRect { get; private set; } + public CameraBox() + { + InitializeComponent(); + Loaded += CameraBox_Loaded; + } + private void CameraBox_Loaded(object sender, RoutedEventArgs e) + { + SetTransform(); + Loaded -= CameraBox_Loaded;//只加载一次SetTransform() + } + + /// + /// 根据viewport尺寸,设置图像的缩放和平移 + /// + private void SetTransform() + { + TransformGroup.Children.Add(scaleTransform); + TransformGroup.Children.Add(translateTransform); + imagebox.RenderTransform = TransformGroup; + viewportWidth = (int)viewport.ActualWidth; + viewportHeight = (int)viewport.ActualHeight; + imageBoxWidth = (int)imagebox.ActualWidth; + imageBoxHeight = (int)imagebox.ActualHeight; + + scale = Math.Min(1.0 * viewportWidth / imageBoxWidth, 1.0 * viewportHeight / imageBoxHeight);//最初放大比 + scaleTransform.ScaleX = scale; + scaleTransform.ScaleY = scale; + + var translateX = (viewportWidth - imageBoxWidth * scale) / 2; + var translateY = (viewportHeight - imageBoxHeight * scale) / 2; + translateTransform.X = translateX; + translateTransform.Y = translateY; + textblock.Text = $"({Math.Round(translateX)},{Math.Round(translateY)}) Zoom:{scale}"; + } + + //鼠标右键弹起:还原图像 + private void viewport_MouseRightButtonUp(object sender, MouseButtonEventArgs e) + { + scaleTransform.ScaleX = scale;//还原最初放大比 + scaleTransform.ScaleY = scale; + var translateX = (viewportWidth - imageBoxWidth * scale) / 2; + var translateY = (viewportHeight - imageBoxHeight * scale) / 2; + translateTransform.X = translateX; + translateTransform.Y = translateY; + } + + //鼠标左键按下 + private void viewport_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + mousePressed = true; + MouseDownPoint = e.GetPosition(viewport); + + ////选框初始位置 + //StartPoint = e.GetPosition(viewport); + //rect.Width = 0; + //rect.Height = 0; + //Canvas.SetLeft(rect, StartPoint.X); + //Canvas.SetTop(rect, StartPoint.Y); + + ////选框坐标显示 + //rectLabel.Text = string.Empty; + //Canvas.SetLeft(rectLabel, StartPoint.X); + //Canvas.SetTop(rectLabel, StartPoint.Y); + //viewport.CaptureMouse(); + + } + + + //鼠标移动 + private void viewport_MouseMove(object sender, MouseEventArgs e) + { + Point point = e.GetPosition(viewport); + MousePoint = point;//更新鼠标位置 + if (!mousePressed) + return; + if (IsMouseSelect) + { + ////表示框选图像 + //rect.Width = point.X - StartPoint.X < 0 ? 0 : point.X - StartPoint.X; + //rect.Height = point.Y - StartPoint.Y < 0 ? 0 : point.Y - StartPoint.Y; + //SelectRect = new Rect(StartPoint.X, StartPoint.Y, rect.Width, rect.Height); + //rectLabel.Text = $"{SelectRect}"; + //Canvas.SetLeft(rectLabel, SelectRect.X + SelectRect.Width); + //Canvas.SetTop(rectLabel, StartPoint.Y); + //if (SelectRect.Width + SelectRect.Height == 0) + //{ + // rectLabel.Text = string.Empty; + //} + } + else + { + //表示移动图像 + translateTransform.X += point.X - MouseDownPoint.X; + translateTransform.Y += point.Y - MouseDownPoint.Y; + MouseDownPoint = point; + textblock.Text = $"({Math.Round(translateTransform.X)},{Math.Round(translateTransform.Y)}) Zoom:{scale}"; + } + } + + //鼠标左键弹起 + private void viewport_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + mousePressed = false; + MouseDownPoint = e.GetPosition(viewport); + viewport.ReleaseMouseCapture(); + + if (IsMouseSelect) + { + OnRectChangedEvent(new RectEventArgs(RectChangedEvent, this, SelectRect, translateTransform.X, translateTransform.Y, scaleTransform.ScaleX)); + } + } + + private void viewport_MouseLeave(object sender, MouseEventArgs e) + { + MousePoint = new Point(-1, -1); + } + + //放大缩小图像 + private void viewport_MouseWheel(object sender, MouseWheelEventArgs e) + { + double scale = e.Delta * 0.0005; + Point point = e.GetPosition(viewport); + Point inverse = TransformGroup.Inverse.Transform(point); + if ((scaleTransform.ScaleX + scale < 0.1) || (scaleTransform.ScaleX + scale > 2)) + { + return; + } + scaleTransform.ScaleX += scale; + scaleTransform.ScaleY += scale; + translateTransform.X = -1 * (inverse.X * scaleTransform.ScaleX - point.X); + translateTransform.Y = -1 * (inverse.Y * scaleTransform.ScaleY - point.Y); + textblock.Text = $"({Math.Round(translateTransform.X)},{Math.Round(translateTransform.Y)}) Zoom:{scale}"; + } + } +} diff --git a/VisionFrame.Base/VisionFrame.Base.csproj b/VisionFrame.Base/VisionFrame.Base.csproj index ac07c5b..ec9f693 100644 --- a/VisionFrame.Base/VisionFrame.Base.csproj +++ b/VisionFrame.Base/VisionFrame.Base.csproj @@ -1,4 +1,4 @@ - + net9.0-windows diff --git a/VisionFrame/App.xaml b/VisionFrame/App.xaml index e30efc4..9e072f3 100644 --- a/VisionFrame/App.xaml +++ b/VisionFrame/App.xaml @@ -7,7 +7,7 @@ ./Assets/Fonts/#iconfont - + ./Assetss/Fonts/#iconfont diff --git a/VisionFrame/Assets/Styles/ButtonStyles.xaml b/VisionFrame/Assets/Styles/ButtonStyles.xaml index e8c04fe..f3814c2 100644 --- a/VisionFrame/Assets/Styles/ButtonStyles.xaml +++ b/VisionFrame/Assets/Styles/ButtonStyles.xaml @@ -1,24 +1,24 @@ - - + + - - - - + + + + + + - - - - + + - + - - + + - - + + - - - - - + + + + + - - -