【问题标题】:Get image coordinates from mouse cursor position on screen (WPF Image control)从屏幕上的鼠标光标位置获取图像坐标(WPF 图像控件)
【发布时间】:2017-11-19 00:01:07
【问题描述】:

我一直在寻找一种解决方案,以透明地向 WPF 图像控件添加平移和缩放功能,我找到了由 Wiesław ŠoltésKonrad Viltersten 开发的解决方案 https://stackoverflow.com/a/6782715/584180,非常出色。

现在我想在控件中添加一个“鼠标点击”事件,这样我就可以在原始图像坐标系中获得点击点的坐标,这样我就可以使用它们来检索像素颜色。

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

我不是 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;
}

【问题讨论】:

  • 如果要获取相对于图像的坐标,则将图像的引用传递给 GetPosition 方法: var mousePos = e.GetPosition(theImage);这是你想要的吗?
  • 您的意思是图像控件会负责将屏幕位置映射到图像位置?图片可能已被缩放和翻译。
  • 如果您希望有人能够帮助您,您可能应该澄清您的要求。您可以先更改问题的标题,因为这似乎与您的实际问题无关...?

标签: c# wpf xaml zooming pan


【解决方案1】:

为了将来参考,我试图实现的是:

    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);
    }

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

【讨论】:

  • 像这样,它适用于所有 Stretch 模式,也适用于 ScrollViewer。
  • 这拯救了一天!
【解决方案2】:

正如 mm8 建议的那样,您可以使用 e.GetPosition(child); 获取所需的位置 ,无需执行任何转换。出于测试目的,我已经覆盖了重置行为。使用the link you provided中的代码,更改

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,但我可以自己进行转换。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多