WPF / C#: Transforming coordinates from an image control to the image source

Posted by Gabriel on Stack Overflow See other posts from Stack Overflow or by Gabriel
Published on 2009-11-05T08:18:19Z Indexed on 2010/04/04 6:13 UTC
Read the original article Hit count: 1608

Filed under:
|
|
|
|

I'm trying to learn WPF, so here's a simple question, I hope:

I have a window that contains an Image element bound to a separate data object with user-configurable Stretch property

<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="{Binding ImageStretch}" />

When the user moves the mouse over the image, I would like to determine the coordinates of the mouse with respect to the original image (before stretching/cropping that occurs when it is displayed in the control), and then do something with those coordinates (update the image).

I know I can add an event-handler to the MouseMove event over the Image control, but I'm not sure how best to transform the coordinates:

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

Now I know I could compare the size of Source to the ActualSize of the control, and then switch on imageCtrl.Stretch to compute the scalars and offsets on X and Y, and do the transform myself. But WPF has all the information already, and this seems like functionality that might be built-in to the WPF libraries somewhere. So I'm wondering: is there a short and sweet solution? Or do I need to write this myself?


EDIT I'm appending my current, not-so-short-and-sweet solution. Its not that bad, but I'd be somewhat suprised if WPF didn't provide this functionality automatically:

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

© Stack Overflow or respective owner

Related posts about wpf

Related posts about coordinate