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 @@
-
-
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
@@ -241,25 +364,69 @@
-
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VisionFrame/VisionFrame.csproj b/VisionFrame/VisionFrame.csproj
index bdb352f..f3adae7 100644
--- a/VisionFrame/VisionFrame.csproj
+++ b/VisionFrame/VisionFrame.csproj
@@ -14,6 +14,7 @@
+
@@ -29,6 +30,9 @@
+
+ Always
+