Home > Back-end >  How do I convert from mouse coordinates to pixel coordinates of a TransformedBitmap?
How do I convert from mouse coordinates to pixel coordinates of a TransformedBitmap?

Time:11-24

My question is similar to enter image description here

However, once you apply a transform, for example changing TheImage.Source = bs; to TheImage.Source = new TransformedBitmap(bs, new RotateTransform(90.0));, hovering over the blue instead gives (~4, ~0).

enter image description here

I think one could look at the actual matrix values of the transform, and determine how to adjust the point in all the various cases, but it seems like there should be an easier solution using the inverse transform.

CodePudding user response:

When an Image element renders a TransformedBitmap, the center point of the Transform is effectively ignored and the bitmap is shifted into an appropriate coordinate range.

Since this shift is not applied to the transfomation of a Point, you have to compensate it, e.g. like this:

var p = e.GetPosition(TheImage);

if (TheImage.Source is BitmapSource bs)
{
    p = new Point(
        p.X * bs.PixelWidth / TheImage.ActualWidth,
        p.Y * bs.PixelHeight / TheImage.ActualHeight);

    if (TheImage.Source is TransformedBitmap tb)
    {
        var w = tb.Source.PixelWidth;
        var h = tb.Source.PixelHeight;

        p = tb.Transform.Inverse.Transform(p);

        p = new Point((p.X   w) % w, (p.Y   h) % h);
    }

    TheLabel.Content = $"x: {(int)p.X}, y: {(int)p.Y}";
}

The above code will however not work correctly when the Transform center is set to a value other than (0,0).

In order to make it work for Transforms with arbitrary center point, you have to clear the offset values in the transform matrix:

var p = e.GetPosition(TheImage);

if (TheImage.Source is BitmapSource bs)
{
    p = new Point(
        p.X * bs.PixelWidth / TheImage.ActualWidth,
        p.Y * bs.PixelHeight / TheImage.ActualHeight);

    if (TheImage.Source is TransformedBitmap tb)
    {
        var w = tb.Source.PixelWidth;
        var h = tb.Source.PixelHeight;
        var t = tb.Transform.Value;
        t.Invert();
        t.OffsetX = 0d;
        t.OffsetY = 0d;

        p = t.Transform(p);

        p = new Point((p.X   w) % w, (p.Y   h) % h);
    }

    TheLabel.Content = $"x: {(int)p.X}, y: {(int)p.Y}";
}
  • Related