问题
I'm trying to rotate image but couldn't get expected result. I've tried with WIn2D but couldn't make image as expected.
My tried Code
public async void Rotate(string originalImagepath, Rect originalImageRect, float degrees)
{
int height = (int)Math.Sqrt(originalImageRect.Width * originalImageRect.Width + originalImageRect.Height * originalImageRect.Height);
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget webCardImage = null;
CanvasBitmap bitmap = null;
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
Vector2 endpoint = new Vector2((float)originalImageRect.Width / 2, (float)originalImageRect.Height / 2);
try
{
webCardImage = new CanvasRenderTarget(device, height, height, logicalDpi);
using (var ds = webCardImage.CreateDrawingSession())
{
ds.Clear(Colors.Transparent);
using (FileStream imageStream = new FileStream(originalImagepath, FileMode.Open))
{
IRandomAccessStream fileStream = imageStream.AsRandomAccessStream();
bitmap = await CanvasBitmap.LoadAsync(device, fileStream);
}
ICanvasImage image = new Transform2DEffect
{
Source = bitmap,
TransformMatrix = Matrix3x2.CreateRotation(degrees, endpoint),
};
var sourceRect = image.GetBounds(ds);
ds.DrawImage(image, new Rect(originalImageRect.X, originalImageRect.Y, originalImageRect.Width, originalImageRect.Height), sourceRect, 1, CanvasImageInterpolation.HighQualityCubic);
}
}
catch (Exception ex)
{
}
//Save Image Code here
}
Expected Output:
My generated Image:
NB: Rect originalImageRect refers main image rect which i want to rotate.
回答1:
When this happens, it means that after your image is rotated, the size of the target rendering rectangle (may be height or width) is smaller than the size of the rotated image, resulting in compression of the image.
I analyzed your code, you tried to create a square with the originalImageRect
diagonal length as the side length, to ensure that the image will not exceed the rendering range when rotating around the center.
This is good, but there are some deviations when rendering.
The image is in the upper left corner of CanvasRenderTarget
by default. If no displacement is performed, the center point is on the upper left when rotating, which means it will still exceed the rendering range.
You can try this:
double height = Math.Sqrt(originalImageRect.Width * originalImageRect.Width + originalImageRect.Height * originalImageRect.Height);
float y = (float)((height - originalImageRect.Height) / 2.0f);
float x = (float)((height - originalImageRect.Width) / 2.0f);
Vector2 endpoint = new Vector2((float)height / 2, (float)height / 2);
try
{
webCardImage = new CanvasRenderTarget(MyCanvas, (float)height, (float)height, logicalDpi);
using (var ds = webCardImage.CreateDrawingSession())
{
// init CanvasBitmap
ICanvasImage image = new Transform2DEffect
{
Source = bitmap,
TransformMatrix = Matrix3x2.CreateTranslation(new Vector2(x,y))
* Matrix3x2.CreateRotation(degrees,endpoint)
};
var sourceRect = image.GetBounds(ds);
ds.DrawImage(image);
}
}
catch (Exception ex)
{
}
We first shift the image, move it to the center of the canvas, and then rotate it around the center of the canvas, so that we can achieve our goal.
In addition, when using the DrawImage()
method, there is no need to additionally define Rect
for rendering constraints.
Thanks.
来源:https://stackoverflow.com/questions/62297514/rotate-image-in-win2d