问题
I was looking for a solution to transparently add panning & zooming capability to a WPF Image control and I have found the solution https://stackoverflow.com/a/6782715/584180, developed by Wiesław Šoltés and Konrad Viltersten, which is outstanding.
Now I would like to add a 'mouse click' event to the control so that I can the coordinates of the clicked point in the original image coordinate system, so I can use them to retrieve the pixel color.
I understand there will be some rounding and if the image is zoomed out the color will not correspond to the actual one displayed on screen. I also understand that the user may click outside the image borders, in that case I expect a null Point or negative coords to be returned.
I am not an expert of the C# way of doing transforms and at the moment I am stuck with this (to be added inside the ZoomBorder.cs class):
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:
As mm8 suggests you can get the location you want using e.GetPosition(child);
, there's no need to perform any transformations. For testing purposes I've overwritten the reset behaviour. Using the code from the link you provided, change
void child_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
this.Reset();
}
to
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());
}
If you rightclick at the same location in the image, you'll get (approximately) the same coordinates, regardless of the pan and zoom.
回答2:
For future reference, what I was trying to achieve is this:
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);
}
Which returns the coordinates of the mouse pointer in the original image system.
来源:https://stackoverflow.com/questions/44585345/get-image-coordinates-from-mouse-cursor-position-on-screen-wpf-image-control