平移后,需要从屏幕上可见的中心点缩放图像

问题描述

当我将渲染变换原点缩放为 (0.5,0.5) 时,它会从图像的中心点缩放并且工作正常。但是当我缩放时平移后,它没有采用图像的可见中心部分,而是采用原始图像的中心。

如何计算平移图像的中心部分。

请找到 working example 并在其中单击增加按钮以增加缩放,然后平移图像并再次增加缩放,但图像并未相对于可见中心进行缩放。

附上图片供参考。

Original center of the image

Center of the image after panning

         <Grid x:Name="grid">
    <Grid.ColumnDeFinitions>
        <ColumnDeFinition Width="2*"/>
        <ColumnDeFinition/>
    </Grid.ColumnDeFinitions>
    <Grid x:Name="panel" MouseWheel="Panel_MouseWheel" Grid.Column="0" Background="Yellow" ClipToBounds="True"
          MouseLeftButtonDown="Panel_MouseLeftButtonDown" MouseMove="Panel_MouseMove"
          MouseLeftButtonUp="Panel_MouseLeftButtonUp">
        <Image x:Name="editorImage" Source="Buldingimage.jpeg" ></Image>
    </Grid>
    <StackPanel Orientation="Vertical" Grid.Column="1">
        <Button Click="Button_Click" Content="Increase"/>
        <Button Content="Decrease" Click="Button_Click_1"></Button>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Zoom factor : "></TextBlock>
            <TextBlock Text="{Binding ZoomFactor}"></TextBlock>
        </StackPanel>
        <Button Content="Reset" Click="Button_Click_2"></Button>
    </StackPanel>
</Grid>
  

       public partial class MainWindow : Window
{
    MatrixTransform ZoomMatrixTransform;
    public MainWindow()
    {
        InitializeComponent();
        grid.DataContext = this;
        updateZoom = true;
    }

    bool updateZoom;

    public int ZoomFactor
    {
        get { return (int)GetValue(ZoomFactorProperty); }
        set { SetValue(ZoomFactorProperty,value); }
    }

    // Using a DependencyProperty as the backing store for ZoomFactor.  This enables animation,styling,binding,etc...
    public static readonly DependencyProperty ZoomFactorProperty =
        DependencyProperty.Register("ZoomFactor",typeof(int),typeof(MainWindow),new PropertyMetadata(100,OnZoomFactorChanged));

    private static void OnZoomFactorChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
        var window = d as MainWindow;
        int factor = (int)e.NewValue;
        if (factor >= 50 && factor <= 400 && window.updateZoom)
            window.PerformZoom(e.NewValue);
    }

    private void PerformZoom(object newValue)
    {          

        float zoomValue = Convert.ToInt32(newValue) / 100f;

        Matrix matrix = Matrix.Identity;
        var scaleX = zoomValue;
        var scaleY = zoomValue;
        matrix.Scale(scaleX,scaleY);

        ZoomMatrixTransform = new MatrixTransform(matrix);

        foreach (UIElement child in panel.Children)
        {
            child.RenderTransformOrigin = new Point(0.5,0.5);
            child.RenderTransform = ZoomMatrixTransform;
        }
     
    }

    private void Button_Click(object sender,RoutedEventArgs e)
    {
        ZoomFactor += 10;
    }

    private void Button_Click_1(object sender,RoutedEventArgs e)
    {
        ZoomFactor -= 10;
    }

    private void Panel_MouseWheel(object sender,MouseWheelEventArgs e)
    {
        var element = sender as UIElement;
        var position = e.GetPosition(panel.Children[0]);

        var matrix = ZoomMatrixTransform == null ? Matrix.Identity : ZoomMatrixTransform.Matrix;

        var scale = e.Delta >= 0 ? 1.1 : (1.0 / 1.1);

        matrix.ScaleAtPrepend(scale,scale,position.X,position.Y);
        var factor = (int)(matrix.M11 * 100);
        updateZoom = false;
        ZoomFactor = factor <= 50 ? 50 : factor >= 400 ? 400 : factor;
        updateZoom = true;

        if (factor >= 50 && factor <= 400)
        {
            ZoomMatrixTransform = new MatrixTransform(matrix);
            foreach (UIElement child in panel.Children)
            {
                child.RenderTransform = ZoomMatrixTransform;
            }
         
        }
    }
    Point start;
    Point origin;
    private void Panel_MouseLeftButtonDown(object sender,MouseButtonEventArgs e)
    {
       
        if ( ZoomMatrixTransform != null && ZoomMatrixTransform.Matrix != Matrix.Identity)
        {
            start = e.GetPosition(panel);
            origin = new Point(ZoomMatrixTransform.Matrix.OffsetX,ZoomMatrixTransform.Matrix.OffsetY);
            editorImage.CaptureMouse();
        }

        Point position;
        if (this.editorImage != null)
            position = e.GetPosition(this.editorImage);
        else
            position = e.GetPosition(panel);
      
    }

    private void Panel_MouseMove(object sender,MouseEventArgs e)
    {
       
        Point position;
        if (this.editorImage != null)
            position = e.GetPosition(this.editorImage);
        else
            position = e.GetPosition(this.panel);
       
        if (editorImage.IsMouseCaptured && ZoomMatrixTransform.Matrix != Matrix.Identity)
        {
            FrameworkElement frameworkElement;
            if (editorImage != null)
                frameworkElement = editorImage;
            else
                frameworkElement = panel;

            var elementBounds = new Rect(frameworkElement.RenderSize);
            var transformedBounds = editorImage.TransformToAncestor(panel).TransformBounds(elementBounds);

            var matrix = ZoomMatrixTransform.Matrix;
            Vector vector = start - e.GetPosition(panel);

            if (transformedBounds.Left < 0 && vector.X <= 0)
                matrix.OffsetX = origin.X - vector.X;
            else if (vector.X >= 0 && transformedBounds.Right >= panel.ActualWidth)
                matrix.OffsetX = origin.X - vector.X;

            if (transformedBounds.Top < 0 && vector.Y <= 0)
                matrix.OffsetY = origin.Y - vector.Y;
            else if (vector.Y >= 0 && transformedBounds.Bottom >= panel.ActualHeight)
                matrix.OffsetY = origin.Y - vector.Y;

            ZoomMatrixTransform.Matrix = matrix;
            foreach (UIElement child in panel.Children)
            {
                child.RenderTransform = ZoomMatrixTransform;
            }
        }
    }

    private void Panel_MouseLeftButtonUp(object sender,MouseButtonEventArgs e)
    {
        editorImage.ReleaseMouseCapture();
    }

    private void Button_Click_2(object sender,RoutedEventArgs e)
    {
        ZoomMatrixTransform.Matrix = Matrix.Identity;
        foreach (UIElement child in panel.Children)
        {
            child.RenderTransform = ZoomMatrixTransform;
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)