WPF - 在滚动查看器中放大图像,并相应地调整滚动条

标签 wpf image-processing

我整理了一个简单的 WPF 应用程序来演示我遇到的问题。我的 XAML 如下:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="427" Width="467" Loaded="MainWindow_OnLoaded">
    <Grid>
        <ScrollViewer Name="MyScrollViewer" CanContentScroll="True">
            <Image Name="MyImage" HorizontalAlignment="Left" VerticalAlignment="Top" MouseWheel="UIElement_OnMouseWheel" MouseDown="MyImage_OnMouseDown" MouseUp="MyImage_OnMouseUp"/>
        </ScrollViewer>
    </Grid>
</Window>

代码隐藏如下:
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void UIElement_OnMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var matrix = MyImage.RenderTransform.Value;

            if (e.Delta > 0)
            {
                matrix.ScaleAt(1.5, 1.5, e.GetPosition(this).X, e.GetPosition(this).Y);
            }
            else
            {
                matrix.ScaleAt(1.0 / 1.5, 1.0 / 1.5, e.GetPosition(this).X, e.GetPosition(this).Y);
            }

            MyImage.RenderTransform = new MatrixTransform(matrix);
        }

        private WriteableBitmap writeableBitmap;

        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            var image = new WriteableBitmap(new BitmapImage(new Uri(@"C:\myImage.png", UriKind.Absolute)));

            MyImage.Width = image.Width;
            MyImage.Height = image.Height;

            image = BitmapFactory.ConvertToPbgra32Format(image);

            writeableBitmap = image;

            MyImage.Source = image;
        }

        private Point downPoint;
        private Point upPoint;

        private void MyImage_OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            downPoint = e.GetPosition(MyImage);
        }

        private void MyImage_OnMouseUp(object sender, MouseButtonEventArgs e)
        {
            upPoint = e.GetPosition(MyImage);

            writeableBitmap.DrawRectangle(Convert.ToInt32(downPoint.X), Convert.ToInt32(downPoint.Y), Convert.ToInt32(upPoint.X), Convert.ToInt32(upPoint.Y), Colors.Red);
            MyImage.Source = writeableBitmap;
        }
    }
}

我使用 Nuget 添加了 WriteableBitmapEx。如果你运行这个,并替换 myImage.png 使用计算机上实际图像的位置,您会发现一个看起来像这样的应用程序:

App

您可以通过单击希望框所在位置的左上角并拖动到希望框所在位置的右下角,在图像上绘制一个框,您会得到一个红色矩形。您甚至可以使用鼠标中键放大,并近距离绘制一个矩形以获得更高的精度,这可以按预期工作。

问题是,当你用鼠标中键滚动时,滚动条不会重新调整,这是我正在创建的程序的要求。我的问题是如何在图像放大时强制滚动查看器上的滚动条重新调整?

我确信它与 ScrollViewer 的 RenderTransform 属性有关,并且我需要在更新图像的 RenderTransform 属性的同时更新它(在 UIElement_OnMouseWheel 上),但我不确定如何进行此操作.

最佳答案

您应该使用 LayoutTransform而不是 RenderTransform在你的形象上。
RenderTransform布局完成后发生并且仅是可视的。 LayoutTransform在布局通过之前完成,因此可以通知 ScrollViewer的新尺寸。

请参阅此处了解更多信息:http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.layouttransform.aspx

关于WPF - 在滚动查看器中放大图像,并相应地调整滚动条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14729853/

相关文章:

c# - WPF MVVM 创建多个数据网格并将项目绑定(bind)到它们

c# - 如何在 WPF 中创建可绑定(bind)属性?

.net - ‘WPF Ribbon Application’ 没有项目模板

android - 如何在单个 ImageView 中获得不同的点击位置

.net - WPF 禁用列表框的 MouseMove 上的项目选择

wpf - LayoutAnchorablePaneGroup 中的 DockWidth

python - OpenCV 找到等高线的中线 [Python]

python - PyTorch 中的数据增强

python - 如何使用python从工程图图像中提取底部?

c++ - BriefDescriptorExtractorImpl 中的 OpenCV 错误 : Bad argument (bytes must be 16, 32 或 64)