在WPF中将坐标从图像控件转换为图像源

Gab*_*iel 7 c# wpf image stretch

我正在尝试学习WPF,所以这是一个简单的问题,我希望:

我有一个窗口,其中包含一个Image元素,该元素绑定到具有用户可配置Stretch属性的单独数据对象

<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="{Binding ImageStretch}" />
Run Code Online (Sandbox Code Playgroud)

当用户将鼠标移动到图像上时,我想确定鼠标相对于原始图像的坐标(在控件中显示时进行拉伸/裁剪之前),然后使用这些坐标执行某些操作(更新图像).

我知道我可以通过Image控件向MouseMove事件添加一个事件处理程序,但我不确定如何最好地转换坐标:

void imageCtrl_MouseMove(object sender, MouseEventArgs e)
{
    Point locationInControl = e.GetPosition(imageCtrl);
    Point locationInImage = ???
    updateImage(locationInImage);
}
Run Code Online (Sandbox Code Playgroud)

现在我知道我可以比较的大小SourceActualSize控制,然后打开imageCtrl.Stretch计算在X和Y的标量和偏移,并做了改造自己.但是WPF已经拥有了所有的信息,这似乎可能是内置于某个WPF库的功能.所以我想知道:有一个短暂而甜蜜的解决方案吗?或者我自己需要写这个?


编辑我正在追加我目前的,不那么短而且甜蜜的解决方案.它并没有那么糟糕,但如果WPF没有自动提供此功能,我会感到有些惊讶:

Point ImgControlCoordsToPixelCoords(Point locInCtrl, 
    double imgCtrlActualWidth, double imgCtrlActualHeight)
{
    if (ImageStretch == Stretch.None)
        return locInCtrl;

    Size renderSize = new Size(imgCtrlActualWidth, imgCtrlActualHeight);
    Size sourceSize = bitmap.Size;

    double xZoom = renderSize.Width / sourceSize.Width;
    double yZoom = renderSize.Height / sourceSize.Height;

    if (ImageStretch == Stretch.Fill)
        return new Point(locInCtrl.X / xZoom, locInCtrl.Y / yZoom);

    double zoom;
    if (ImageStretch == Stretch.Uniform)
        zoom = Math.Min(xZoom, yZoom);
    else // (imageCtrl.Stretch == Stretch.UniformToFill)
        zoom = Math.Max(xZoom, yZoom);

    return new Point(locInCtrl.X / zoom, locInCtrl.Y / zoom);
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ven 8

如果您使用ViewBox可能会更容易.例如:

<Viewbox Stretch="{Binding ImageStretch}">
    <Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="None"/>
</Viewbox>
Run Code Online (Sandbox Code Playgroud)

然后当你去调用GetPosition(..)时,WPF会自动考虑缩放.

void imageCtrl_MouseMove(object sender, MouseEventArgs e) 
{ 
    Point locationInControl = e.GetPosition(imageCtrl);
}
Run Code Online (Sandbox Code Playgroud)