在画布上缩放和翻译图像时遇到的问题

时间:2017-01-05 12:51:22

标签: c# wpf transformation

在工作中,我们使用C#/ WPF和MVVM模式构建了一个复杂的应用程序。在应用程序中,我们有一个画布。在该画布上,我们在画布的中心显示一个图像。我们希望能够缩放和翻译图像。我们可以指定比例因子来缩放画布上的所有元素。要将变换应​​用于图像,我们将TransformGroup绑定到XAML中图像的RenderTransform属性。 TransformGroup是在视图模型中构建的,首先添加ScaleTransform,然后添加TranslateTransform。

转换以这样的方式指定:

// View model
// Global fileds
private ScaleTransform scaleTransform = new ScaleTransform(1, 1);
private TranslateTransform translateTransform = new TranslateTransform(0, 0);
private Vector totalShift = new Vector(0, 0);

...

public void ApplyTransformations() {
    scaleTransform.ScaleX = scaleFactor;
    scaleTransform.ScaleY = scaleFactor;

    translateTransform.X = canvasCenter.X - imageWidth / 2;
    translateTransform.Y = canvasCenter.Y - imageHeight / 2;
}

现在我们可以在更改比例因子时正确缩放图像。

要启用图像转换,我们将图像放入Thumb。拇指提供了一个DragDelta事件,它为我们提供了x和y方向的移动。每次我们拖动拇指时,此移位都会添加到totalShift中。以下方法是视图模型的一部分,由视图后面的代码中的DragDelta事件处理程序调用。

public void addShift(double horizontal, double vertical) {
    totalShift.X += horizontal;
    totalShift.Y += vertical;
}

ApplyTransformations()修改如下:

private double prevScaleFactor = 0;

public void ApplyTransformations() {
    double oldCenterX = scaleTransform.CenterX;
    double oldCenterY = scaleTransform.CenterY;

    scaleTransform.CenterX = -totalShift.X;
    scaleTransform.CenterY = -totalShift.Y;

    translateTransform.X = (canvasCenter.X - imageWidth / 2) + (scaleTransform.CenterX - oldCenterX) * prevScaleFactor;
    translateTransform.Y = (canvasCenter.Y - imageHeight / 2) + (scaleTransform.CenterY - oldCenterY) * prevScaleFactor;

    scaleTransform.ScaleX = scaleFactor;
    scaleTransform.ScaleY = scaleFactor;

    prevScaleFactor = scaleFactor;
}

问题: 假设scaleFactor为1.5,我们在x方向上拖动图像100 px。当我们执行ApplyTransformation()时,图像在x方向上没有移位100 px,而只有100 / 1.5 = 66.67 px。这意味着移位在应用之前会进行缩放。

我们怎样才能做到这一点?任何帮助表示赞赏。提前谢谢。

修改 TransformGroup以这样的方式构建:

private TransformGroup _transform = new TransformGroup();
public TransformGroup Transform {
    get {
        _transformGroup.Children.Clear();
        _transformGroup.Children.Add(scaleTransform);
        _transformGroup.Children.Add(translateTransform);
    }
}

如果我这样做,就会出现上述问题。

修改2

我创建了一个MCVE,因此您可以运行它并查看问题。将比例因子更改为不等于1.0的值。然后用鼠标拖离黑色画布,使其远离红点(中心点)并再次更改比例因子。现在黑色画布似乎有点跳跃。

1 个答案:

答案 0 :(得分:0)

我相信你是以错误的顺序应用你的转换。首先,你正在翻译,然后你正在扩展。您应该尝试将缩放更改应用于图像,然后对图像进行任何旋转(在此示例中,您不使用任何),然后进行任何翻译。

有关转换顺序的更多信息,请查看此MSDN文章:https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspx