KeiStory

WPF Image Zoom 및 Panning 처리하기

 

이미지를 마우스 휠로 키웠다 줄였다 하는 Zoom 과 마우스 클릭이로 이동하는 Panning 를 구현하는 방법입니다.

MainWindow.xaml

<Window
    x:Class="WPFTest.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"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <StackPanel>
        <Grid x:Name="LayoutRoot" Height="500">
            <Grid.RowDefinitions>
                <RowDefinition Height="52.92" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Border
                Name="border"
                Grid.Row="1"
                Background="Gray"
                ClipToBounds="True">
                <Image
                    Name="image"
                    ClipToBounds="True"
                    Opacity="1"
                    RenderTransformOrigin="0.5,0.5"
                    Source="kei.jpg" />
            </Border>
        </Grid>
    </StackPanel>
</Window>

 

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace WPFTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// 원본 포인트입니다.
        /// </summary>
        private Point origin;

        /// <summary>
        /// 시작 포인트입니다.
        /// </summary>
        private Point start;

        public MainWindow()
        {
            InitializeComponent();

            TransformGroup transformGroup = new TransformGroup();
            ScaleTransform scaleTransform = new ScaleTransform();
            transformGroup.Children.Add(scaleTransform);

            TranslateTransform translateTransform = new TranslateTransform();
            transformGroup.Children.Add(translateTransform);

            image.RenderTransform = transformGroup;
            image.MouseWheel += image_MouseWheel;
            image.MouseLeftButtonDown += image_MouseLeftButtonDown;
            image.MouseLeftButtonUp += image_MouseLeftButtonUp;
            image.MouseMove += image_MouseMove;
        }

        /// <summary>
        /// 마우스 휠 움직임에 따라 Zoon In/Out 합니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void image_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            var transform = (ScaleTransform)((TransformGroup)image.RenderTransform).Children.First(c => c is ScaleTransform);

            double zoom = e.Delta > 0 ? .2 : -.2;
            transform.ScaleX += zoom;
            transform.ScaleY += zoom;
        }

        /// <summary>
        /// 좌클릭에 따라 패닝을 시작합니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            image.CaptureMouse();
            var translateTransform = (TranslateTransform)((TransformGroup)image.RenderTransform).Children.First(c => c is TranslateTransform);
            start = e.GetPosition(border);
            origin = new Point(translateTransform.X, translateTransform.Y);
        }

        /// <summary>
        /// 마우스 우버튼 놓을때 패닝되던 이미지가 멈춥니다
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            image.ReleaseMouseCapture();
        }

        /// <summary>
        /// 마우스 움직임에 따라 이미지가 패닝됩니다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void image_MouseMove(object sender, MouseEventArgs e)
        {
            if (!image.IsMouseCaptured) return;
            var translateTransform = (TranslateTransform)((TransformGroup)image.RenderTransform).Children.First(c => c is TranslateTransform);
            Vector v = start - e.GetPosition(border);
            translateTransform.X = origin.X - v.X;
            translateTransform.Y = origin.Y - v.Y;
        }
    }
}

* 예시 코드는 진행했던 프로젝트에서 사용했던 것입니다.

결과

반응형

'코딩 > WPF' 카테고리의 다른 글

WPF Freezable  (1) 2024.09.27
WPF GraphicsPath 를 PathGeometry 로 변환하기  (0) 2024.09.23
WPF Image to BitmapImage  (0) 2024.09.11
WPF BooleanToVisibilityConverter  (0) 2024.09.11
WPF DataTrigger MultiDataTrigger 처리  (0) 2024.09.11

공유하기

facebook twitter kakaoTalk kakaostory naver band