图像区域添加右键菜单功能

This commit is contained in:
李伟
2026-04-23 16:53:26 +08:00
parent d5b421b811
commit c2650e737b
2 changed files with 96 additions and 3 deletions
+14 -2
View File
@@ -41,8 +41,20 @@
<Grid Grid.Row="1">
<roi:PolygonRoiCanvas x:Name="RoiCanvas"
ImageSource="{Binding ImageSource}"
Background="White" />
<!-- 测量结果浮层(已移至画布内线段附近显示) -->
Background="White">
<roi:PolygonRoiCanvas.ContextMenu>
<ContextMenu>
<MenuItem Header="放大" Click="ZoomIn_Click" />
<MenuItem Header="缩小" Click="ZoomOut_Click" />
<MenuItem Header="适应窗口" Click="ResetView_Click" />
<Separator />
<MenuItem Header="保存原始图像" Click="SaveOriginalImage_Click" />
<MenuItem Header="保存结果图像" Click="SaveResultImage_Click" />
<Separator />
<MenuItem Header="清除所有绘制" Click="ClearAllMeasurements_Click" />
</ContextMenu>
</roi:PolygonRoiCanvas.ContextMenu>
</roi:PolygonRoiCanvas>
</Grid>
<!-- 图像信息栏 -->
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;
using XP.ImageProcessing.RoiControl.Controls;
using XplorePlane.Events;
using XplorePlane.ViewModels;
@@ -204,10 +207,12 @@ namespace XplorePlane.Views
StrokeThickness = 1.5,
Cursor = Cursors.Hand
};
// 禁止测量点上弹出右键菜单
dot.SetValue(ContextMenuService.IsEnabledProperty, false);
dot.MouseLeftButtonDown += Dot_Down;
dot.MouseMove += Dot_Move;
dot.MouseLeftButtonUp += Dot_Up;
dot.MouseRightButtonDown += Dot_RightClick;
dot.PreviewMouseRightButtonUp += Dot_RightClick;
return dot;
}
@@ -320,5 +325,81 @@ namespace XplorePlane.Views
}
#endregion
#region
private void ZoomIn_Click(object sender, RoutedEventArgs e) => RoiCanvas.ZoomScale = Math.Min(10.0, RoiCanvas.ZoomScale * 1.2);
private void ZoomOut_Click(object sender, RoutedEventArgs e) => RoiCanvas.ZoomScale = Math.Max(0.1, RoiCanvas.ZoomScale / 1.2);
private void ResetView_Click(object sender, RoutedEventArgs e) => RoiCanvas.ResetView();
private void ClearAllMeasurements_Click(object sender, RoutedEventArgs e)
{
if (_measureOverlay != null)
{
_measureOverlay.Children.Clear();
_groups.Clear();
}
_pendingDot = null;
_pendingPoint = null;
if (DataContext is ViewportPanelViewModel vm)
{
vm.ResetMeasurementState();
vm.ImageInfo = "已清除所有测量";
}
}
private void SaveOriginalImage_Click(object sender, RoutedEventArgs e)
{
if (DataContext is not ViewportPanelViewModel vm || vm.ImageSource is not BitmapSource bitmap)
{
MessageBox.Show("当前没有可保存的图像", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
SaveBitmapToFile(bitmap, "保存原始图像");
}
private void SaveResultImage_Click(object sender, RoutedEventArgs e)
{
// 截取整个图像区域(含测量标注覆盖层)
var target = FindChildByName<Canvas>(RoiCanvas, "mainCanvas");
if (target == null)
{
MessageBox.Show("当前没有可保存的图像", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
var width = (int)target.ActualWidth;
var height = (int)target.ActualHeight;
if (width == 0 || height == 0) return;
var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(target);
SaveBitmapToFile(rtb, "保存结果图像");
}
private static void SaveBitmapToFile(BitmapSource bitmap, string title)
{
var dialog = new SaveFileDialog
{
Title = title,
Filter = "PNG 图像|*.png|BMP 图像|*.bmp|JPEG 图像|*.jpg",
DefaultExt = ".png"
};
if (dialog.ShowDialog() != true) return;
BitmapEncoder encoder = System.IO.Path.GetExtension(dialog.FileName).ToLower() switch
{
".bmp" => new BmpBitmapEncoder(),
".jpg" or ".jpeg" => new JpegBitmapEncoder(),
_ => new PngBitmapEncoder()
};
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using var fs = new FileStream(dialog.FileName, FileMode.Create);
encoder.Save(fs);
}
#endregion
}
}