I'm looking for a way to rotate a rectangular image (or any image for that matter) around its center point using Win2D.
This snippet is from within the OnDraw method for the Win2D canvas:
var redBitMap = _images[1];
var yellowBitMap = _images[2];
var rect = new Rect(topLeft.X, topLeft.Y, _width, _height);
_drawingSession.DrawImage(redBitMap, rect);
ICanvasImage image = new Transform2DEffect
{
Source = yellowBitMap,
TransformMatrix = Matrix3x2.CreateRotation((float)(60 * Math.PI / 180)),
};
var sourceRect = image.GetBounds(_drawingSession);
_drawingSession.DrawImage(image, rect), sourceRect, 1, CanvasImageInterpolation.HighQualityCubic);
This method gives me my image rotated by 60 degrees, but the image ends up being drawn at the wrong coordinates, skewed and smaller than the intended image.
Interestingly enough, if I change the size of the rectangle so that it is square (making the height the same as the width), the image is no longer skewed.
After giving it more thought, here is what is happening:
So, the yellow rectangle represents the image I want to rotate (on center) by 60 degrees. The red rectangle that is anchored to the top left corner is what is happening when I rotate it. The big blue box is the new rectangle created that is determined by the image.GetBounds statement.
When I try to draw the image back to the original coordinates, you can see from the right hand image that it's causing the image to be both skewed and shrunk because the source rectangle is no longer the same size or shape as the target rectangle.
If my geometry skills were better, I could surely calculate the bounds of the new rectangle and apply them to the correct location back onto the canvas. But alas, it's been too many years since high-school math for me. On a one-off calculation, I'm sure I could figure it out - but not when the shape of the source image might change.
Jet, your suggestion helped me find the answer. What I needed to do was not use the ScaleEffect, but that's what gave me the clue I needed. The final draw image needed to take into account the changing size (much the same idea as the ScaleEffect. This left me with the following line of code:
args.DrawingSession.DrawImage(image, new Rect(topLeft.X + (_width - sourceRect.Width)/2, topLeft.Y + (_height - sourceRect.Height)/2, sourceRect.Width, sourceRect.Height), sourceRect, 1, CanvasImageInterpolation.HighQualityCubic)