从屏幕鼠标位置获取图像坐标(WPF图像控件)

4

我正在寻找一种方法,在 WPF Image 控件中透明地添加平移和缩放功能,并且我已经发现了这个解决方案https://dev59.com/ynRB5IYBdhLWcg3wCjcV#6782715,由Wiesław ŠoltésKonrad Viltersten开发,非常出色。

现在我想将“鼠标单击”事件添加到控件中,以便我可以获取原始图像坐标系中单击点的坐标,以便我可以使用它们来检索像素颜色。

我知道会有一些四舍五入和如果图像缩小,则颜色将不对应于实际显示在屏幕上的颜色。 我也明白用户可能会在图像边界外单击,在这种情况下,我希望返回一个空点或负坐标。

我不是 C# 变换专家,目前我被卡住了(需要添加到 ZoomBorder.cs 类内):

public Point GetImageCoordsAt(MouseButtonEventArgs e)
{
    if (child != null)
    {
        var tt = GetTranslateTransform(child);
        var mousePos = e.GetPosition(this);
        var transformOrigin = new Point(tt.X, tt.Y);

        return mousePos; // Wrong: how do I transform this?
    }

    return null;
}

1
如果您想获取相对于图像的坐标,请将图像的引用传递给GetPosition方法:var mousePos = e.GetPosition(theImage); 这是您想要的吗? - mm8
你的意思是图像控件会负责将屏幕位置映射到图像位置吗?图像可能已经被缩放和平移。 - Lordalcol
如果你想让别人帮助你,最好澄清你的需求。你可以从修改问题的标题开始,因为这个标题似乎与你实际的问题无关...? - mm8
2个回答

11

以后参考,我试图实现的是这个:

    public Point GetImageCoordsAt(MouseButtonEventArgs e)
    {
        if (child != null && child.IsMouseOver)
        {
            var controlSpacePosition = e.GetPosition(child);
            var imageControl = this.Child as Image;
            var mainViewModel = ((MainViewModel)base.DataContext);
            if (imageControl != null && imageControl.Source != null)
            {
                // Convert from control space to image space
                var x = Math.Floor(controlSpacePosition.X * imageControl.Source.Width / imageControl.ActualWidth);
                var y = Math.Floor(controlSpacePosition.Y * imageControl.Source.Height / imageControl.ActualHeight);

                return new Point(x, y);
            }
        }
        return new Point(-1, -1);
    }

返回鼠标指针在原始图像系统中的坐标。


1
就像这样,它可以与所有的Stretch模式一起使用,并且也可以在ScrollViewer中使用。 - FreddyFlares
1
这拯救了全局! - teusbenschop

1

正如mm8所建议的那样,您可以使用e.GetPosition(child);获取所需的位置,无需进行任何转换。为了测试目的,我已覆盖了重置行为。使用您提供的链接中的代码,更改

void child_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    this.Reset();
}

public Point GetImageCoordsAt(MouseButtonEventArgs e)
{
    if (child != null && child.IsMouseOver)
    {
        return e.GetPosition(child);
    }
    return new Point(-1, -1);
}

void child_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show(GetImageCoordsAt(e).ToString());
}

如果您在图像的相同位置右键单击,无论平移和缩放,您将获得(大约)相同的坐标。

这仍然给我基于Image控件大小的坐标,而不是原始的BitmapSource,但我可以自己进行转换。谢谢。 - Lordalcol

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