C# Wpf 图片按照鼠标中心缩放和平移

7 篇文章 0 订阅

C# Wpf 图片按照鼠标中心缩放和平移

1、缩放事件

MouseWheel(object sender, MouseWheelEventArgs e)

2、平移相关的事件

MouseMove(object sender, MouseEventArgs e)
MouseDown(object sender, MouseButtonEventArgs e)
MouseUp(object sender, MouseButtonEventArgs e)

3、图片平移实现

public Point StartPoint;
public Point Origin;



    private void ImageEx_MouseUp(object sender, MouseButtonEventArgs e)
    {
        this.ReleaseMouseCapture();
    }

    private void ImageEx_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Released) return;
        TranslateTransform transform = group.Children[1] as TranslateTransform;
        var startPoint = StartPoint - e.GetPosition(this);
        transform.X = Origin.X - startPoint.X;
        transform.Y = Origin.Y - startPoint.Y;
    }



    private void ImageEx_MouseDown(object sender, MouseButtonEventArgs e)
    {
        StartPoint = e.GetPosition(this);
        TranslateTransform trans = group.Children[1] as TranslateTransform;
        Origin = new Point(trans.X, trans.Y);
        this.CaptureMouse();
    }

4、图片缩放实现

private void ImageEx_MouseWheel(object sender, MouseWheelEventArgs e)
{
    Point relative = e.GetPosition(image);
    double zoom = e.Delta > 0 ? 0.1 : -0.1;
    ScaleTransform scale = group.Children[0] as ScaleTransform;
    TranslateTransform trans = group.Children[1] as TranslateTransform;
    double absoluteX;
    double absoluteY;

    absoluteX = relative.X * scale.ScaleX + trans.X;
    absoluteY = relative.Y * scale.ScaleY + trans.Y;

    scale.ScaleX += zoom;
    scale.ScaleY += zoom;

    trans.X = absoluteX - relative.X * scale.ScaleX;
    trans.Y = absoluteY - relative.Y * scale.ScaleY;
}

5、完整代码

1、xaml

<UserControl x:Class="WpfApp1.ImageEx"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp1"
             mc:Ignorable="d" 
             xmlns:panAndZoom="clr-namespace:Wpf.Controls.PanAndZoom;assembly=Wpf.Controls.PanAndZoom"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
        <Image Visibility="Collapsed" Source="{Binding CurrentImage}" x:Name="image">
            <Image.RenderTransform>
                <TransformGroup x:Name="group">
                    <ScaleTransform />
                    <TranslateTransform />
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
    </Grid>

</UserControl>

2、CS

namespace WpfApp1
{
    /// <summary>
    /// ImageEx.xaml 的交互逻辑
    /// </summary>
    public partial class ImageEx : UserControl
    {
        public Point StartPoint;
        public Point Origin;
        public BitmapSource CurrentImage { get; set; }

        public ImageEx()
        {
            InitializeComponent();
            CurrentImage = new BitmapImage(new Uri("C:\\Users\\Desktop\\111.png"));

            this.MouseDown += ImageEx_MouseDown;
            this.MouseMove += ImageEx_MouseMove;
            this.MouseUp += ImageEx_MouseUp;
            this.MouseWheel += ImageEx_MouseWheel;
        }

        private void ImageEx_MouseUp(object sender, MouseButtonEventArgs e)
        {
            this.ReleaseMouseCapture();
        }

        private void ImageEx_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            Point relative = e.GetPosition(image);
            double zoom = e.Delta > 0 ? 0.1 : -0.1;
            ScaleTransform scale = group.Children[0] as ScaleTransform;
            TranslateTransform trans = group.Children[1] as TranslateTransform;
            double absoluteX;
            double absoluteY;

            absoluteX = relative.X * scale.ScaleX + trans.X;
            absoluteY = relative.Y * scale.ScaleY + trans.Y;

            scale.ScaleX += zoom;
            scale.ScaleY += zoom;

            trans.X = absoluteX - relative.X * scale.ScaleX;
            trans.Y = absoluteY - relative.Y * scale.ScaleY;
        }

        private void ImageEx_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Released) return;
            TranslateTransform transform = group.Children[1] as TranslateTransform;
            var startPoint = StartPoint - e.GetPosition(this);
            transform.X = Origin.X - startPoint.X;
            transform.Y = Origin.Y - startPoint.Y;
        }



        private void ImageEx_MouseDown(object sender, MouseButtonEventArgs e)
        {
            StartPoint = e.GetPosition(this);
            TranslateTransform trans = group.Children[1] as TranslateTransform;
            Origin = new Point(trans.X, trans.Y);
            this.CaptureMouse();
        }

    }

}

3、调用方法

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <local:ImageEx  x:Name="imageEx" />
    </Grid>
</Window>

可以通过以下方式实现: 1. 在XAML文件中,创建一个ScrollViewer控件,并将其中的Content属性设置为一个Image控件。 2. 给ScrollViewer和Image控件分别设置一个RenderTransform属性,并创建一个TransformGroup对象作为属性值。 3. 在TransformGroup对象中添加一个ScaleTransform和TranslateTransform对象,用于控制缩放平移操作。 4. 在代码中,通过鼠标滚轮事件和鼠标移动事件来实现缩放平移操作。 具体实现可以参考以下代码: ```xml <ScrollViewer x:Name="scrollView"> <Image x:Name="image" Source="image.jpg"> <Image.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </Image.RenderTransform> </Image> <ScrollViewer.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </ScrollViewer.RenderTransform> </ScrollViewer> ``` ```csharp private Point _lastMousePos; private void Image_MouseWheel(object sender, MouseWheelEventArgs e) { double scale = e.Delta > 0 ? 1.1 : 0.9; ScaleTransform scaleTransform = ((TransformGroup)scrollView.RenderTransform).Children.OfType<ScaleTransform>().First(); scaleTransform.ScaleX *= scale; scaleTransform.ScaleY *= scale; } private void Image_MouseDown(object sender, MouseButtonEventArgs e) { _lastMousePos = e.GetPosition(scrollView); } private void Image_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { TranslateTransform translateTransform = ((TransformGroup)scrollView.RenderTransform).Children.OfType<TranslateTransform>().First(); ScaleTransform scaleTransform = ((TransformGroup)scrollView.RenderTransform).Children.OfType<ScaleTransform>().First(); Point currMousePos = e.GetPosition(scrollView); translateTransform.X += (currMousePos.X - _lastMousePos.X) / scaleTransform.ScaleX; translateTransform.Y += (currMousePos.Y - _lastMousePos.Y) / scaleTransform.ScaleY; _lastMousePos = currMousePos; } } ``` 在代码中,通过获取鼠标滚轮事件和鼠标移动事件,分别实现缩放平移操作。在缩放操作中,通过ScaleTransform对象的ScaleX和ScaleY属性来控制缩放比例。在平移操作中,通过TranslateTransform对象的X和Y属性来控制平移距离。注意,在平移操作中,需要获取当前鼠标位置和上一次鼠标位置的差值,并且除以缩放比例,才能得到正确的平移距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑非不退

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值