WPF zoom in an image around the mouse

//xaml
<Window x:Class="WpfApp197.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"
        WindowState="Maximized"
        xmlns:local="clr-namespace:WpfApp197"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Image x:Name="img" Source="/Images/1.jpg"
                   MouseWheel="img_MouseWheel"                  
                   Stretch="Uniform">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="scaler"/>
                    <TranslateTransform x:Name="translater"/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
    </Grid>
</Window>



//xaml.cs
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 WpfApp197
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const double ZoomFactor = 1.1;
        private const double MinZoom = 0.1;
        private const double MaxZoom = 10.0;
        private double scaleValue = 1.0;
        public MainWindow()
        {
            InitializeComponent();
        } 
        private void img_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            // Get mouse position relative to the image
            Point mousePos = e.GetPosition(img);

            // Calculate the absolute position before zoom
            Point absolutePos = new Point(mousePos.X * scaler.ScaleX + translater.X,
                mousePos.Y * scaler.ScaleY + translater.Y);

            // Determine zoom direction and factor
            double zoomValue = e.Delta > 0 ?  ZoomFactor : 1/ZoomFactor;
            double newScale = scaleValue * zoomValue;

            // Apply zoom limits
            newScale = Math.Max(MinZoom, Math.Min(MaxZoom, newScale));
            zoomValue = newScale / scaleValue;

            if (zoomValue != 1.0)
            {
                scaleValue = newScale;

                // Apply the new scale
                scaler.ScaleX = scaleValue;
                scaler.ScaleY = scaleValue;

                // Adjust translation to zoom around mouse position
                translater.X = absolutePos.X - mousePos.X * scaler.ScaleX;
                translater.Y = absolutePos.Y - mousePos.Y * scaler.ScaleY;
            }
            Application.Current?.Dispatcher.BeginInvoke(new Action(() =>
            {
                this.Title = $"ScaleValue:{scaleValue}";
            }));
            e.Handled = true;
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2025-04-06 16:45  FredGrit  阅读(12)  评论(0)    收藏  举报