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}"; } } }