123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- using MeterVision.Patch;
- using MeterVision.Single;
- using Ookii.Dialogs.Wpf;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.IO;
- 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.UC
- {
- /// <summary>
- /// UCImage1.xaml 的交互逻辑
- /// </summary>
- public partial class UCImage : UserControl, INotifyPropertyChanged
- {
- private double zoomFactor = 1.0;
- private double rotationAngle = 0;
- private Point? dragStartPoint; // 用于记录鼠标按下的位置
- // Properties to bind to the XAML
- public double ZoomFactor
- {
- get => zoomFactor;
- set
- {
- zoomFactor = value;
- ApplyTransforms();
- }
- }
- public double RotationAngle
- {
- get => rotationAngle;
- set
- {
- rotationAngle = value;
- ApplyTransforms();
- }
- }
- public event PropertyChangedEventHandler PropertyChanged;
- protected void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- // 定义依赖属性 ImageSource,用于绑定图片路径
- public static readonly DependencyProperty ImageSourceProperty =
- DependencyProperty.Register("ImageSource", typeof(string), typeof(UCImage), new PropertyMetadata(null, OnImageSourceChanged));
- public string ImageSource
- {
- get => (string)GetValue(ImageSourceProperty);
- set => SetValue(ImageSourceProperty, value);
- }
- // 在 UCImage 类中添加一个私有字段
- private bool _loadedEventSubscribed = false;
- // 当 ImageSource 发生变化时,更新 Image 控件的源
- private static void OnImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ucImage = d as UCImage;
- if (ucImage != null && e.NewValue is string imagePath && File.Exists(imagePath))
- {
- ucImage.pnlImageCtl.Visibility = Visibility.Visible;
- ucImage.zoomFactor = 1.0;
- ucImage.rotationAngle = 0;
- // 将图片路径转换为 BitmapImage
- ucImage.imgViewer.Source = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute));
- // 使用 Dispatcher 延迟调用
- //ucImage.Dispatcher.BeginInvoke(new Action(() =>
- //{
- // ucImage.CalculateInitialZoomFactor();
- //}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
- // 订阅 imgViewer 的 Loaded 事件
- if (!ucImage._loadedEventSubscribed)
- {
- ucImage._loadedEventSubscribed = true;
- ucImage.imgViewer.Loaded += (sender, args) =>
- {
- ucImage.imgViewer.Loaded -= (s, a) => { };
- ucImage.CalculateInitialZoomFactor();
- ucImage._loadedEventSubscribed = false; // 重置标志位以便下次使用
- };
- }
- }
- else
- {
- ucImage.imgViewer.Source = null;
- ucImage.pnlImageCtl.Visibility = Visibility.Collapsed;
- }
- }
- private string _imageName;
- public string ImageName
- {
- get => _imageName;
- set
- {
- if (_imageName != value)
- {
- _imageName = value;
- OnPropertyChanged(nameof(ImageName));
- }
- }
- }
- public UCImage()
- {
- InitializeComponent();
- this.DataContext = this;
- }
- private void ZoomIn_Click(object sender, RoutedEventArgs e)
- {
- // 增加缩放因子
- ZoomFactor *= 1.2;
- }
- private void ZoomOut_Click(object sender, RoutedEventArgs e)
- {
- // 减小缩放因子
- if (zoomFactor > 0.1) // 防止缩放因子过小
- {
- ZoomFactor /= 1.2;
- }
- }
- private void ZoomFit_Click(object sender, RoutedEventArgs e)
- {
- CalculateInitialZoomFactor();
- }
- private void RotateLeft_Click(object sender, RoutedEventArgs e)
- {
- // 向左旋转
- RotationAngle -= 90;
- }
- private void RotateRight_Click(object sender, RoutedEventArgs e)
- {
- // 向右旋转
- RotationAngle += 90;
- }
- private void ApplyTransforms()
- {
- // Ensure the zoom factor stays within reasonable bounds
- if (ZoomFactor < 0.1) ZoomFactor = 0.1;
- if (ZoomFactor > 10.0) ZoomFactor = 10.0;
- // Create a ScaleTransform to apply the zoom
- ScaleTransform scaleTransform = new ScaleTransform(ZoomFactor, ZoomFactor);
- // Create a RotateTransform to apply the rotation
- RotateTransform rotateTransform = new RotateTransform(RotationAngle);
- // Combine the scale and rotation transforms
- TransformGroup transformGroup = new TransformGroup();
- transformGroup.Children.Add(scaleTransform);
- transformGroup.Children.Add(rotateTransform);
- // Apply the combined transform to the image
- imgViewer.LayoutTransform = transformGroup;
- // Center the image in the ScrollViewer
- CenterImageInScrollViewer();
- }
- // Center the image in the ScrollViewer
- private void CenterImageInScrollViewer()
- {
- if (scrollViewer != null && imgViewer != null)
- {
- // Calculate the center of the image
- double imageWidth = imgViewer.ActualWidth * ZoomFactor;
- double imageHeight = imgViewer.ActualHeight * ZoomFactor;
- // Calculate the center of the ScrollViewer
- double scrollViewerWidth = scrollViewer.ViewportWidth;
- double scrollViewerHeight = scrollViewer.ViewportHeight;
- // Calculate the horizontal and vertical offsets to center the image
- double horizontalOffset = (imageWidth - scrollViewerWidth) / 2;
- double verticalOffset = (imageHeight - scrollViewerHeight) / 2;
- // Set the scroll position to center the image
- scrollViewer.ScrollToHorizontalOffset(horizontalOffset > 0 ? horizontalOffset : 0);
- scrollViewer.ScrollToVerticalOffset(verticalOffset > 0 ? verticalOffset : 0);
- }
- }
- private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
- {
- if (Keyboard.Modifiers == ModifierKeys.Control)
- {
- if (e.Delta > 0)
- {
- zoomFactor *= 1.2; // Increase zoom factor by 20%
- }
- else
- {
- zoomFactor /= 1.2; // Decrease zoom factor by 20%
- }
- //e.Handled = true;
- }
- }
- // 当用户按下鼠标左键时,记录按下的位置
- private void Image_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- dragStartPoint = e.GetPosition(scrollViewer);
- }
- // 当用户拖动鼠标时,根据鼠标的移动调整 ScrollViewer 的滚动位置
- private void Image_PreviewMouseMove(object sender, MouseEventArgs e)
- {
- if (dragStartPoint.HasValue && e.LeftButton == MouseButtonState.Pressed)
- {
- Point currentPoint = e.GetPosition(scrollViewer);
- Vector delta = Point.Subtract(dragStartPoint.Value, currentPoint);
- // 调整 ScrollViewer 的滚动位置
- scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + delta.X);
- scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + delta.Y);
- // 更新拖动起点为当前点,以防止累积偏移
- dragStartPoint = currentPoint;
- }
- }
- private void Image_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- dragStartPoint = null;
- }
- // 计算初始缩放比例,使得图片正好适应 ScrollViewer 的视口
- public void CalculateInitialZoomFactor()
- {
- if (scrollViewer != null && imgViewer != null)
- {
- // 获取 ScrollViewer 的视口尺寸
- double scrollViewerWidth = scrollViewer.ViewportWidth;
- double scrollViewerHeight = scrollViewer.ViewportHeight;
- // 获取图片的实际尺寸
- double imageWidth = imgViewer.ActualWidth;
- double imageHeight = imgViewer.ActualHeight;
- // 如果图片还没有加载完成,等待加载完成后再次尝试计算
- if (double.IsNaN(imageWidth) || double.IsNaN(imageHeight))
- {
- //imgViewer.Loaded += (s, ev) => CalculateInitialZoomFactor();
- return;
- }
- // 计算水平和垂直方向的缩放比例
- double scaleX = scrollViewerWidth / imageWidth;
- double scaleY = scrollViewerHeight / imageHeight;
- // 选择较小的缩放比例,以确保图片完全适应 ScrollViewer
- double initialZoomFactor = Math.Min(scaleX, scaleY);
- // 确保缩放比例不会小于 0.1 或大于 10.0
- if (initialZoomFactor < 0.1) initialZoomFactor = 0.1;
- if (initialZoomFactor > 10.0) initialZoomFactor = 10.0;
- // 应用初始缩放比例
- ZoomFactor = initialZoomFactor;
- // 中心化图片
- CenterImageInScrollViewer();
- }
- }
- public void ImageZoom(bool zoomIn, MouseWheelEventArgs e)
- {
- if (zoomIn)
- {
- ZoomFactor *= 1.1; // Zoom in
- }
- else
- {
- ZoomFactor /= 1.1; // Zoom out
- }
- Point mousePosition = e.GetPosition(imgViewer);
- double prevZoomFactor = 1 / ZoomFactor;
- double offsetX = (mousePosition.X * ZoomFactor - mousePosition.X * prevZoomFactor) / prevZoomFactor;
- double offsetY = (mousePosition.Y * ZoomFactor - mousePosition.Y * prevZoomFactor) / prevZoomFactor;
- scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + offsetX);
- scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offsetY);
- }
- private void ImageSave_Click(object sender, RoutedEventArgs e)
- {
- if (imgViewer.Source != null)
- {
- ExportImage(imgViewer);
- }
- }
- private void ExportImage(Image imageControl)
- {
- if (imageControl.Source is BitmapImage bitmapImage)
- {
- try
- {
- // 1. 获取原始文件路径
- string sourcePath = bitmapImage.UriSource.LocalPath;
- if (string.IsNullOrEmpty(sourcePath) || !File.Exists(sourcePath))
- {
- MessageBox.Show("无法确定原始文件路径或文件不存在。");
- return;
- }
- // 2. 弹出保存对话框
- VistaSaveFileDialog saveFileDialog = new VistaSaveFileDialog
- {
- FileName = Path.GetFileName(sourcePath), // 默认文件名
- DefaultExt = Path.GetExtension(sourcePath),
- Filter = $"Image Files (*{Path.GetExtension(sourcePath)})|*{Path.GetExtension(sourcePath)}|All Files (*.*)|*.*"
- };
- if (saveFileDialog.ShowDialog() == true)
- {
- // 3. 直接复制文件
- File.Copy(sourcePath, saveFileDialog.FileName, true);
- //MessageBox.Show("图片导出成功。");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show($"导出失败: {ex.Message}");
- }
- }
- else
- {
- MessageBox.Show("Image控件中没有有效的图像。");
- }
- }
- ///////////////////////////////////////////////////////////////////////
- }
- }
|