【问题标题】:Zoom on image according to mouse position in wpf根据wpf中的鼠标位置放大图像
【发布时间】:2015-12-17 09:23:36
【问题描述】:

我在放大画布中的图像时遇到了一些问题。我正在考虑使用matrixtransform,但它不起作用。它返回给我一个我不明白的异常!这是 XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Click="Button_Click"/>

    <ScrollViewer Grid.Row="2"
                  Name="scroll"
                  HorizontalScrollBarVisibility="Auto" 
                  VerticalScrollBarVisibility="Auto">

        <Canvas Name="Container"
                ClipToBounds="True"
                MouseWheel="Container_MouseWheel"
               >

            <Image  Name="ImageSource"
                >
                <Image.LayoutTransform>
                    <MatrixTransform/>
                </Image.LayoutTransform>
            </Image>
        </Canvas>
    </ScrollViewer>
</Grid>

后面的代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Bitmap Bmp = new Bitmap(@"C:\Desktop\image1.bmp");
    ImageSource.Source = CreateBitmapSourceFromGdiBitmap(Bmp);
    Container.Width = Bmp.Width;
    Container.Height = Bmp.Height;
}

private void Container_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var element = sender as UIElement;
    var position = e.GetPosition(element);
    var transform = element.RenderTransform as MatrixTransform;
    var matrix = transform.Matrix;
    var scale = e.Delta >= 0 ? 1.1 : (1.0 / 1.1); // choose appropriate scaling factor

    matrix.ScaleAtPrepend(scale, scale, position.X, position.Y);
    transform.Matrix = matrix;
}

如果有人可以给我一个很好的提示,谢谢!

【问题讨论】:

    标签: c# wpf image canvas zooming


    【解决方案1】:

    替换

    transform.Matrix = matrix;
    

    element.RenderTransform = new MatrixTransform( matrix );
    

    它有效;)

    【讨论】:

    • @SnowballTwo 我的scrollviewer 还是有问题,大小或滚动没有根据缩放调整大小:/
    • 你应该摆脱你的容器,将图像设置为滚动查看器的第一个孩子,设置图像的宽度和高度与图像源最初匹配,并使用 LayoutTransform 而不是 RenderTransform。未测试...
    • 我在后面的 coe 中找不到如何使用带有矩阵变换的布局变换。如果你能给我一个提示;)谢谢!
    • 只需用 LayoutTransforms 替换所有 RenderTransforms...它们都是“Transform”类型...您可以按 ctrl + shift + f 并搜索项目中的所有用法
    【解决方案2】:

    我不知道你是否解决了这个问题。但是这里的 Xaml 代码可以让您很好地缩放。它可以工作,您可以使用 ScrollVider 的滚动条来平移图像。

    <ScrollViewer x:Name="vbxImageViewBox" 
                  CanContentScroll="False" 
                  HorizontalScrollBarVisibility="Auto"
                  VerticalScrollBarVisibility="Auto">
    
        <Grid x:Name="grdItcMain" Margin="5">
             <Grid.LayoutTransform>
                <TransformGroup>
                    <ScaleTransform 
                        ScaleX="{Binding Path=ScaleFactor, 
                                 ElementName=this, 
                                 Mode=OneWay}" 
                        ScaleY="{Binding Path=ScaleFactor, 
                                 ElementName=this, 
                                 Mode=OneWay}" />
                </TransformGroup>
            </Grid.LayoutTransform>
            <Rectangle Fill="DeepSkyBlue" Stretch="Fill" />
            <Image MouseWheel="Image_MouseWheel"
                Source="{Binding PreviewSource,
                         ElementName=this,
                         Mode=OneWay}"
                Stretch="Fill" />
        </Grid>
    </ScrollViewer>
    
    private const double _smallChange = 0.1;
    private double _scaleFactor;
    public double ScaleFactor 
    { 
        get 
        { 
            return _scaleFactor; 
        } 
        set 
        { 
            _scaleFactor = value; 
            OnPropertyChanged("ScaleFactor"); 
        } 
    }
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
         double scaleX = (grdItcMain.ActualWidth - 20) / 1920;
         double scaleY = (grdItcMain.ActualHeight - 20) / 1080;
         double dScale = Math.Min(scaleX, scaleY);
         ScaleFactor = dScale; //size to fit initially
    }
    
    private void Image_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (e.Delta > 0)
        {
            if ((ScaleFactor + _smallChange) > 25.0)
            {
                return;
            }
    
            ScaleFactor += _smallChange;
    
            vbxImageViewBox.LineRight();
            vbxImageViewBox.LineRight();
            vbxImageViewBox.LineRight();
            vbxImageViewBox.LineRight();
            vbxImageViewBox.LineRight();
    
            vbxImageViewBox.LineDown();
            vbxImageViewBox.LineDown();
            vbxImageViewBox.LineDown();
            vbxImageViewBox.LineDown();
            vbxImageViewBox.LineDown();
            vbxImageViewBox.LineDown();
        }
        else
        {
            if ((ScaleFactor - _smallChange) < 0.001)
            {
                return;
            }
            ScaleFactor -= _smallChange;
    
            vbxImageViewBox.LineLeft();
            vbxImageViewBox.LineLeft();
            vbxImageViewBox.LineLeft();
            vbxImageViewBox.LineLeft();
            vbxImageViewBox.LineLeft();
    
            vbxImageViewBox.LineUp();
            vbxImageViewBox.LineUp();
            vbxImageViewBox.LineUp();
            vbxImageViewBox.LineUp();
            vbxImageViewBox.LineUp();
            vbxImageViewBox.LineUp();
            }
        }
    

    这不是一个完美的解决方案,但它有效且易于实施。

    道格

    【讨论】:

      【解决方案3】:

      任何寻找解决方案的人都应该尝试由 Wiesław Šoltés 创建的出色解决方案here。只需粘贴答案中显示的代码即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-12
        • 1970-01-01
        • 2011-05-03
        • 2020-03-16
        • 2021-11-13
        • 2013-03-26
        • 1970-01-01
        相关资源
        最近更新 更多