MatrixTransform an Image

# MatrixTransform an Image

• 24 aprilie 2012 12:15

I have a BitmapImage. Within that image, I have 2 reference points, R1 and R2. I also know the width and height.

On my DrawingContext, I have 2 destination points, D1 and D2. I want to draw my image so that R1 and R2 match D1 and D2 and the image gets squeezed/expanded and rotated as needed.

I guess I would do dc.PushTransform() with MatrixTransform before doing dc.DrawImage()... Any ideas how? Thanks.

DNS for Windows Azure dnsazure.com

### Toate mesajele

• 24 aprilie 2012 13:15
Moderator

"I guess I would do dc.PushTransform() with MatrixTransform"

Well yes but this is probably easier to understand if you use a transform group instead of building a MatrixTransform directly. Here's an example:

```            TransformGroup transform = new TransformGroup();

Point r1 = new Point(0, image.Height / 2.0);
Point r2 = new Point(image.Width, image.Height / 2.0);

Point d1 = new Point(20, 150); // some random D1/D2 coords
Point d2 = new Point(80, 70);

Vector v1 = r2 - r1;
Vector v2 = d2 - d1;

transform.Children.Add(new TranslateTransform(-r1.X, -r1.Y)); // change the origin to R1
transform.Children.Add(new ScaleTransform(v2.Length / v1.Length, 1.0)); // scale along X axis
transform.Children.Add(new RotateTransform(Vector.AngleBetween(v1, v2))); // rotate to match the direction of D1-D2
transform.Children.Add(new TranslateTransform(d1.X, d1.Y)); // finally move the image to D1

dc.PushTransform(transform);
dc.DrawImage(image, new Rect(0, 0, image.Width, image.Height));
dc.Pop();```

Note that scaling is done only along the X axis, it's not possible to scale along Y without additional points.
• 24 aprilie 2012 13:44

Wow, thanks, you made my day.

DNS for Windows Azure dnsazure.com

• 29 aprilie 2012 08:42

Thanks Mike this really helps. Can I have a follow up question?

Question 1: Instead of having R1 and R2 as reference points, but having R'1 and R'2. Should I use translate R'1 to R1 first, then translate back D'1 to D1?

Question 2: If I have an additional point (R'3), may I know how can I do the Scale along Y also?

(R'1 R'2 and R'3 are some points inside the image instead of on the edge of the image)

• 30 aprilie 2012 03:01

I have a known BitmapImage (width=400, height=100). Inside this image, I have 2 known reference points, R'1 (100,50) and R'2 (300,50). Also, I know R0 (0,0).

(R'1 R'2 and R'3 are some points inside the image instead of on the edge of the image)

On my DrawingContext, I have 2 destinations points, D'1 (300,300) and D'2 (400,400). I want to draw my image so that R'1 and R'2 match D'1 and D'2 and the image gets squeezed/expanded and rotated as needed. However, I don't know D0.

I tried the code suggested by Mike. However, the image doesn't render correctly

```TransformGroup transform = new TransformGroup();

//Point r1 = new Point(0, image.Height / 2.0);
//Point r2 = new Point(image.Width, image.Height / 2.0);
Point r1 = new Point(100, 50);
Point r2 = new Point(300, 50);

Point d1 = new Point(300, 300);
Point d2 = new Point(400, 400);

Vector v1 = r2 - r1;
Vector v2 = d2 - d1;

transform.Children.Add(new TranslateTransform(-r1.X, -r1.Y)); // change the origin to R1
transform.Children.Add(new ScaleTransform(v2.Length / v1.Length, 1.0)); // scale along X axis
transform.Children.Add(new RotateTransform(Vector.AngleBetween(v1, v2))); // rotate to match the direction of D1-D2
transform.Children.Add(new TranslateTransform(d1.X, d1.Y)); // finally move the image to D1

dc.PushTransform(transform);
dc.DrawImage(image,
new Rect(0, 0, // d0
image.Width, image.Height)); // this doesn't render correctlydc.DrawEllipse(new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)), null, d1, thickness, thickness); // this renders correctlydc.DrawEllipse(new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)), null, d2, thickness, thickness); // this renders correctlydc.Pop();```

Questions 2: If I have an additional point (R'3) (200,10) , may I know how can I do the Scale along Y also?

Questions 3: Which topic/book should I look into if I want to know more about this regarding do some AR using WPF? (DirectX, XNA ??)

Thank you very much.

• 30 aprilie 2012 07:46
Moderator

1: nope, you don't need an additional translation.

2: for this we can use the distance between the R3/D3 points and the R1R2/D1D2 lines do determine the y scaling factor. Here's an update for the relevant part of the code:

```            Point r1 = new Point(51, 28);
Point r2 = new Point(177, 28);
Point r3 = new Point(111, 7);

Point d1 = new Point(335, 118);
Point d2 = new Point(395, 60);
Point d3 = new Point(345, 75);

Vector vr21 = r2 - r1;
Vector vd21 = d2 - d1;

Vector vr31 = r3 - r1;
Vector vd31 = d3 - d1;

double y1 = Vector.CrossProduct(vr31, vr21) / vr21.Length;
double y2 = Vector.CrossProduct(vd31, vd21) / vd21.Length;