[UWP]如何在C#UWP中旋转Win2D绘图项? [英] [UWP] How to Rotate Win2D Drawings Item in C# UWP?

查看:134
本文介绍了[UWP]如何在C#UWP中旋转Win2D绘图项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DrawingUI类,它绘制一个矩形,图像项位于中心。

I have a DrawingUI class that draws a rectangle with image item in center.

public class DrawingUI :  IDrawingUI
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Rotation { get; set; }
        public CanvasBitmap Image { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        public bool Editing { get; set; }

        public Size Bound { get; set; }

        public Rect Region
        {
            get
            {
                return new Rect(X - Width / 2, Y - Height / 2, Width, Height);
            }
        }
        public Rect RightTopRegion
        {
            get
            {
                return new Rect(X + Width / 2 + 2 - 8, Y - Height / 2 - 2 - 8, 16, 16);
            }
        }
        public Rect RightBottomRegion
        {
            get
            {
                return new Rect(X + Width / 2 + 2 - 8, Y + Height / 2 + 2 - 8, 16, 16);
            }
        }
        public void SyncWH()
        {
            Height = (Image.Size.Height / Image.Size.Width) * Width;
        }
        /// <summary>
        /// Draw
        /// </summary>
        /// <param name="graphics"></param>
        public void Draw(CanvasDrawingSession graphics, float scale)
        {
            if (Image != null)
            {
                graphics.DrawImage(Image, new Rect((X - (Width / 2)) * scale, (Y - (Height / 2)) * scale, Width * scale, Height * scale));
            }
            else
            {
                graphics.DrawText("loading...", ((float)X - 12) * scale, ((float)Y - 2) * scale, Colors.Orange, new Microsoft.Graphics.Canvas.Text.CanvasTextFormat() { FontSize = 11 });
            }

            if (Editing && scale == 1) //If it is edited state and there is no zoom
            {
                graphics.DrawRectangle(new Rect(X - Width / 2 - 2, Y - Height / 2 - 2, Width + 4, Height + 4), Windows.UI.Colors.Orange, 0.5f, new CanvasStrokeStyle() { DashStyle = CanvasDashStyle.DashDot });
                graphics.FillCircle((float)(X + Width / 2 + 2), (float)(Y - Height / 2 - 2), 8, Colors.Orange);  //Cancel button
                graphics.DrawLine((float)(X + Width / 2 + 2) - 4, (float)(Y - Height / 2 - 2) - 4, (float)(X + Width / 2 + 2) + 4, (float)(Y - Height / 2 - 2) + 4, Colors.White);
                graphics.DrawLine((float)(X + Width / 2 + 2) - 4, (float)(Y - Height / 2 - 2) + 4, (float)(X + Width / 2 + 2) + 4, (float)(Y - Height / 2 - 2) - 4, Colors.White);
                graphics.FillCircle((float)(X + Width / 2 + 2), (float)(Y + Height / 2 + 2), 8, Colors.Orange); //Scale
                graphics.DrawLine((float)(X + Width / 2 + 2 - 4), (float)(Y + Height / 2 + 2 - 4), (float)(X + Width / 2 + 2 + 4), (float)(Y + Height / 2 + 2 + 4), Colors.White);
                graphics.DrawLine((float)(X + Width / 2 + 2 - 4), (float)(Y + Height / 2 + 2 - 4), (float)(X + Width / 2 + 2 - 4), (float)(Y + Height / 2 + 2), Colors.White);
                graphics.DrawLine((float)(X + Width / 2 + 2 - 4), (float)(Y + Height / 2 + 2 - 4), (float)(X + Width / 2 + 2), (float)(Y + Height / 2 + 2 - 4), Colors.White);
                graphics.DrawLine((float)(X + Width / 2 + 2 + 4), (float)(Y + Height / 2 + 2 + 4), (float)(X + Width / 2 + 2), (float)(Y + Height / 2 + 2 + 4), Colors.White);
                graphics.DrawLine((float)(X + Width / 2 + 2 + 4), (float)(Y + Height / 2 + 2 + 4), (float)(X + Width / 2 + 2 + 4), (float)(Y + Height / 2 + 2), Colors.White);
            }
        }
    }




我的主页.xaml

<Page
    x:Class="CSharp_Studio.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CSharp_Studio"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
    d:DesignHeight="400"
    xmlns:views="using:CSharp_Studio.Views"
    mc:Ignorable="d">
    <Grid >
        <canvas:CanvasControl 
                x:Name="MainCanvas"
                RelativePanel.AlignHorizontalCenterWithPanel="True"
                RelativePanel.AlignVerticalCenterWithPanel="True"
                Draw="MainCanvas_Draw" 
                ManipulationMode="TranslateX,TranslateY,Rotate"
                ManipulationStarted="MainCanvas_ManipulationStarted"
                ManipulationCompleted="MainCanvas_ManipulationCompleted"
                ManipulationDelta="MainCanvas_ManipulationDelta"
                Tapped="MainCanvas_Tapped"></canvas:CanvasControl>
    </Grid>
</Page>

My MainPage.cs

My MainPage.cs

public sealed partial class MainPage : Page
    {
        IDrawingUI drawingUI;
        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += MainPage_Loaded;

        }

        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            DrawItem();
        }
        private async void DrawItem(string fileName = "ms-appx:///Images/web.jpg")
        {
            drawingUI = new DrawingUI()
            {
                Editing = true,
                Height = 100,
                Width = 100,
                Image = null,
                X = 150,
                Y = 150,
            };
            this.MainCanvas.Invalidate();
            CanvasDevice device = CanvasDevice.GetSharedDevice();
            var img = await CanvasBitmap.LoadAsync(device, new Uri(fileName));
            if (img != null)
            {
                (drawingUI as DrawingUI).Width = img.Size.Width;
                (drawingUI as DrawingUI).Height = img.Size.Height;
                (drawingUI as DrawingUI).Image = img;
            }
        }
        private void MainCanvas_ManipulationStarted(object sender, Windows.UI.Xaml.Input.ManipulationStartedRoutedEventArgs e)
        {
            if (drawingUI != null)
            {
                if ((drawingUI as DrawingUI).Region.Contains(e.Position))                 {
                    ManipulationType = 3;
                    PrePosition = e.Position;
                    (drawingUI as DrawingUI).Editing = true;
                }
                if ((drawingUI as DrawingUI).RightBottomRegion.Contains(e.Position) && (drawingUI as DrawingUI).Editing)                {
                    ManipulationType = 4;
                    PrePosition = e.Position;
                }
                MainCanvas.Invalidate();
            }
        }
        int ManipulationType = 0;
        Point? PrePosition;
        private void MainCanvas_ManipulationCompleted(object sender, Windows.UI.Xaml.Input.ManipulationCompletedRoutedEventArgs e)
        {

        }

        private void MainCanvas_ManipulationDelta(object sender, Windows.UI.Xaml.Input.ManipulationDeltaRoutedEventArgs e)
        {
            if (drawingUI != null && PrePosition != null)
            {
                var deltaX = e.Position.X - PrePosition.Value.X;
                var deltaY = e.Position.Y - PrePosition.Value.Y;
                if (ManipulationType == 3)  //mobile
                {
                    (drawingUI as DrawingUI).X += deltaX;
                    (drawingUI as DrawingUI).Y += deltaY;

                    (drawingUI as DrawingUI).Rotation = e.Delta.Rotation;
                }
                else if (ManipulationType == 4)  //Scale
                {
                    (drawingUI as DrawingUI).Width += deltaX * 2;
                    (drawingUI as DrawingUI).SyncWH();  //Only need to set the width height automatically sync
                }
                PrePosition = e.Position;

                MainCanvas.Invalidate();
            }
        }

        private void MainCanvas_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {

        }

        private void MainCanvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
        {
            var target = GetDrawing(true);  //
            if (target != null)
            {
                args.DrawingSession.DrawImage(target);
            }
        }
        private CanvasRenderTarget GetDrawing(bool edit = true)
        {
            MainCanvas.Width = Window.Current.Bounds.Width;
            MainCanvas.Height = Window.Current.Bounds.Height;
            double w = 200, h = 200;  // Canvas size
            if (edit)  //Edit status
            {
                w = MainCanvas.ActualWidth;
                h = MainCanvas.ActualHeight;
            }
           
            var scale = edit ? 1 : w / MainCanvas.Width;  //scaling ratio

            CanvasDevice device = CanvasDevice.GetSharedDevice();
            CanvasRenderTarget target = new CanvasRenderTarget(device, (float)w, (float)h, 96);
            using (CanvasDrawingSession graphics = target.CreateDrawingSession())
            {
                //Draw the background
                graphics.Clear(Colors.Black);
                if (drawingUI != null)
                {
                    drawingUI.Draw(graphics, (float)scale);
                }
            }
            return target;
        }
    }

结果很好我可以调整大小或拖动到CanvasControl的任何位置但是如何实现此绘图的旋转?

The result is good I can resize or drag to any position of CanvasControl but how to implement the rotation for this drawing?

//结果

amazestudio24

amazestudio24

推荐答案


嗨amazestudio24,



你可以使用

Matrix3x2.CreateRotation
创建旋转图像。如下代码:

You could use Matrix3x2.CreateRotation to create a rotate image. Like the following code:



 private void canvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
        {
            args.DrawingSession.Transform *= Matrix3x2.CreateRotation((float)Math.PI / 2, new Vector2(200));
            args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
        }






Transform2Erffect 。它也可以创建旋转效果。像这样:

Also, after searching the document, I found another effect called Transform2DEffect. It could also create rotation effect. Like this:


ICanvasImage image = new Transform2DEffect
{
   Source = SourceBitMap,
   TransformMatrix = Matrix3x2.CreateRotation((float)(60 * Math.PI / 180)),
};





您可以参考官方的Win2D示例获取更多信息:

https://github.com /Microsoft/Win2D/blob/master/samples/ExampleGallery/Shared/EffectsExample.xaml.cs

You could refer the official Win2D sample for more information: https://github.com/Microsoft/Win2D/blob/master/samples/ExampleGallery/Shared/EffectsExample.xaml.cs


最好的问候,


罗伊


这篇关于[UWP]如何在C#UWP中旋转Win2D绘图项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆