如何在WPF C# 4.0中构建放大镜?

6

我需要将一个大图像的用户光标下方的缩放部分渲染出来。

我的图像在 Grid 中,并且在 XAML 中定义如下:

<Grid x:Name="RootImgGrid" Background="#FF333333" >
    <Viewbox x:Name="imgViewBox"  Margin="1,1,1,1" Stretch="Fill" >
        <Canvas x:Name="imgCanvas"  ClipToBounds="True" Width="{Binding ElementName=RootImgGrid, Path=ActualWidth}" Height="{Binding ElementName=RootImgGrid, Path=ActualHeight}">
            <Image x:Name="imgObj" MouseWheel="img_MouseWheel" Cursor="Hand" MouseMove="Img_MouseMove" MouseDown="Img_MouseDown" MouseUp="Img_MouseUp"  >
                <Image.RenderTransform>
                    <TransformGroup x:Name="imgTransformGroup">
                        <ScaleTransform x:Name="imgScaleTransform"></ScaleTransform>
                        <TranslateTransform x:Name="imgTranslateTransform"></TranslateTransform>
                    </TransformGroup>
                </Image.RenderTransform>
                <Image.LayoutTransform>
                    <RotateTransform x:Name="imgRotateTransform"></RotateTransform>
                </Image.LayoutTransform>
            </Image>
        </Canvas>
    </Viewbox>
</Grid>

我有一个放大区域,应该在我的光标下出现放大2倍的图像。
<Viewbox x:Name="imgViewBoxMagnifier" Width="400" Height="90">
    <Canvas  x:Name="imgCanvasMagnifier" Width="400" Height="90">
        <Canvas.Clip>
            <RectangleGeometry Rect="0,0,400,90" />
        </Canvas.Clip>
        <Image  x:Name="imgMagnifier" Margin="2" Width="400" Height="90">
            <Image.RenderTransform>
                <TransformGroup x:Name="imgMagnifierTransformGroup">
                    <ScaleTransform x:Name="imgMagnifierScaleTransform"></ScaleTransform>
                    <TranslateTransform x:Name="imgMagnifierTranslateTransform"></TranslateTransform>
                </TransformGroup>
            </Image.RenderTransform>
            <Image.LayoutTransform>
                <RotateTransform x:Name="imgMagnifierRotateTransform"></RotateTransform>
            </Image.LayoutTransform>
        </Image>
    </Canvas>
</Viewbox>

现在,在我的.CS代码中,我有一个函数应该显示放大的图像:
public void Magnifier(Canvas imgCanvas, Image imgObject, Image imgMagnifier, MouseEventArgs e)
    {
        Int32 width = 400;
        Int32 height = 90;

        if (imgMagnifier.Source != imgObject.Source)
        {
            imgMagnifier.Source = imgObject.Source;
        }

        Size size = imgObject.RenderSize;
        RotateTransform rt = (RotateTransform)imgObject.LayoutTransform;
        TranslateTransform tt = (TranslateTransform)((TransformGroup)imgObject.RenderTransform).Children[1];
        ScaleTransform st = (ScaleTransform)((System.Windows.Media.TransformGroup)(imgObject.RenderTransform)).Children[0];
        Double x = e.GetPosition(imgCanvas).X - tt.X;
        Double y = e.GetPosition(imgCanvas).Y - tt.Y;
        Point pos = e.MouseDevice.GetPosition(imgCanvas);

        TransformGroup transformGroup = new TransformGroup();
        ScaleTransform scale = new ScaleTransform();

        scale.CenterX = x;
        scale.CenterY = y;
        scale.ScaleX = st.ScaleX * 10;
        scale.ScaleY = st.ScaleY * 10;
        transformGroup.Children.Add(scale);

        TranslateTransform translate = new TranslateTransform();
        translate.X = ??????????????????;
        translate.Y = ??????????????????;
        transformGroup.Children.Add(translate);

        imgMagnifier.RenderTransform = transformGroup;

    }

我该如何找到那些“?????????”的正确值?

translate.X = -x * 10 / (size.Width / 400);
translate.Y = -y * 10 / (size.Height / 90);

它显示了正确的图像,进行了缩放,但它不显示我鼠标下方的图像区域。
提前致谢。
2个回答

9

由于我没有找到任何打包解决方案,因此我从头开始开发了一个完全功能的Microsoft VS 2010项目放大镜Zoom C# 4.0 WPF。

它包括缩小、放大、旋转、适应宽度以及放大的区域。

欢迎下载并使其更好。

WPF Magnifier C# 4.0

希望您喜欢。如果您觉得有用,请点赞。

public void Magnifier(Canvas imgCanvas, Image imgObject, Canvas imgCanvasMagnifier, Image imgMagnifier, MouseEventArgs e)
    {
        Double width = imgCanvasMagnifier.Width;
        Double height = imgCanvasMagnifier.Height;
        Int32 zoom = 3;

        String txtDebug = String.Empty;
        String txtZoom = String.Empty;

        if (imgMagnifier.Source != imgObject.Source)
        {
            imgMagnifier.Source = imgObject.Source;
        }

        Size size = imgObject.RenderSize;
        RotateTransform rt = (RotateTransform)imgObject.LayoutTransform;
        TranslateTransform tt = (TranslateTransform)((TransformGroup)imgObject.RenderTransform).Children[1];
        ScaleTransform st = (ScaleTransform)((System.Windows.Media.TransformGroup)(imgObject.RenderTransform)).Children[0];
        Double x = e.GetPosition(imgCanvas).X - tt.X;
        Double y = e.GetPosition(imgCanvas).Y - tt.Y;
        Point pos = e.MouseDevice.GetPosition(imgCanvas);
        var wnd = Canvas.GetTop(imgObject);

        TransformGroup transformGroup = new TransformGroup();
        ScaleTransform scale = new ScaleTransform();

        scale.ScaleX = st.ScaleX * zoom;
        scale.ScaleY = st.ScaleY * zoom;

        RotateTransform rotate = new RotateTransform();
        rotate.Angle = rt.Angle;

        TranslateTransform translate = new TranslateTransform();

        Double centerX = st.CenterX * (st.ScaleX - 1);
        Double centerY = st.CenterY * (st.ScaleY - 1);

        if (rt.Angle == 0)
        {
            translate.X = -(x + centerX) / st.ScaleX;
            translate.Y = -(y + centerY) / st.ScaleY;
            scale.CenterX = (x + centerX) / st.ScaleX;
            scale.CenterY = (y + centerY) / st.ScaleY;
        }
        if (rt.Angle == 90)
        {
            translate.X = -(x + centerX) / st.ScaleX;
            translate.Y = -(y + centerY) / st.ScaleY;
            translate.X += imgObject.ActualHeight * st.ScaleX * zoom;
            scale.CenterX = (x + centerX) / st.ScaleX;
            scale.CenterY = (y + centerY) / st.ScaleY;
        }

        if (rt.Angle == 180)
        {
            translate.X = -(x + centerX) / st.ScaleX;
            translate.Y = -(y + centerY) / st.ScaleY;
            translate.X += imgObject.ActualWidth * st.ScaleX * zoom;
            translate.Y += imgObject.ActualHeight * st.ScaleY * zoom;
            scale.CenterX = (x + centerX) / st.ScaleX;
            scale.CenterY = (y + centerY) / st.ScaleY;
        }

        if (rt.Angle == 270)
        {
            translate.X = -(x + centerX) / st.ScaleX;
            translate.Y = -(y + centerY) / st.ScaleY;
            translate.Y += imgObject.ActualWidth * st.ScaleX * zoom;
            scale.CenterX = (x + centerX) / st.ScaleX;
            scale.CenterY = (y + centerY) / st.ScaleY;
        }

        translate.X += width / 2;
        translate.Y += height / 2;

        transformGroup.Children.Add(rotate);
        transformGroup.Children.Add(scale);
        transformGroup.Children.Add(translate);


        imgMagnifier.RenderTransform = transformGroup;

    }

1
检查一下在Github上的代码,这样人们搜索时就可以索引它了,怎么样? - Candide

0

提醒一下:我以前从未接触过WPF,所以我抓住这个机会来学习。这是我的解决方案:

首先,我在两个图像上禁用了拉伸功能:Stretch="None",并删除了图像的高度和宽度定义。

然后,代码如下:

    double xFactor = 2, yFactor = 2;

    Size size = imgObject.RenderSize;
    Size magSize = new Size(width: imgMagnifier.RenderSize.Width * xFactor,
                            height: imgMagnifier.RenderSize.Height * yFactor);

    Point pos = e.MouseDevice.GetPosition(imgCanvas);

    var transformGroup = new TransformGroup();
    var scale = new ScaleTransform();
    scale.CenterX = 0;
    scale.CenterY = 0;
    scale.ScaleX = xFactor;
    scale.ScaleY = yFactor;
    transformGroup.Children.Add(scale);

    var translate = new TranslateTransform();
    translate.X = -pos.X * xFactor + imgCanvasMagnifier.Width / 2;
    translate.Y = -pos.Y * yFactor + imgCanvasMagnifier.Height / 2;
    transformGroup.Children.Add(translate);

    imgMagnifier.RenderTransform = transformGroup;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接