using CPF.Drawing; using System; using System.Collections.Generic; using System.Text; #if !Net4 using SkiaSharp; #endif namespace ConsoleApp1 { /// /// 3D变换只能支持Skia /// public class ThreeDEffect1 : CPF.Effects.Effect { /// /// 0到1 /// [CPF.PropertyMetadata(0.5f)] public float Value { get { return GetValue(); } set { SetValue(value); } } /// /// 翻转方向 /// [CPF.PropertyMetadata(TaperSide.Left)] public TaperSide TaperSide { get { return GetValue(); } set { SetValue(value); } } [CPF.PropertyMetadata(TaperCorner.Both)] public TaperCorner TaperCorner { get { return GetValue(); } set { SetValue(value); } } public override void DoEffect(DrawingContext dc, Bitmap bitmap) { #if !Net4 float taperFraction = Value; TaperSide side = TaperSide; var size = new SKSize(bitmap.Width, bitmap.Height); SKMatrix taperMatrix = TaperTransform.Make(size, TaperSide, TaperCorner, taperFraction); //// Display the matrix in the lower-right corner //SKSize matrixSize = matrixDisplay.Measure(taperMatrix); //matrixDisplay.Paint(canvas, taperMatrix, // new SKPoint(info.Width - matrixSize.Width, // info.Height - matrixSize.Height)); // Center bitmap on canvas float x = 0; float y = 0; SKMatrix matrix = SKMatrix.MakeTranslation(-x, -y); SKMatrix.PostConcat(ref matrix, taperMatrix); SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(x, y)); var canvas = (dc as CPF.Skia.SkiaDrawingContext).SKCanvas; var mat = canvas.TotalMatrix; dc.AntialiasMode = AntialiasMode.AntiAlias; canvas.SetMatrix(mat.PreConcat(matrix)); canvas.DrawBitmap((bitmap.BitmapImpl as CPF.Skia.SkiaBitmap).Bitmap, x, y); #endif } } public enum TaperSide { Left, Top, Right, Bottom } public enum TaperCorner { LeftOrTop, RightOrBottom, Both } #if !Net4 static class TaperTransform { public static SKMatrix Make(SKSize size, TaperSide taperSide, TaperCorner taperCorner, float taperFraction) { SKMatrix matrix = SKMatrix.MakeIdentity(); switch (taperSide) { case TaperSide.Left: matrix.ScaleX = taperFraction; matrix.ScaleY = taperFraction; matrix.Persp0 = (taperFraction - 1) / size.Width; switch (taperCorner) { case TaperCorner.RightOrBottom: break; case TaperCorner.LeftOrTop: matrix.SkewY = size.Height * matrix.Persp0; matrix.TransY = size.Height * (1 - taperFraction); break; case TaperCorner.Both: matrix.SkewY = (size.Height / 2) * matrix.Persp0; matrix.TransY = size.Height * (1 - taperFraction) / 2; break; } break; case TaperSide.Top: matrix.ScaleX = taperFraction; matrix.ScaleY = taperFraction; matrix.Persp1 = (taperFraction - 1) / size.Height; switch (taperCorner) { case TaperCorner.RightOrBottom: break; case TaperCorner.LeftOrTop: matrix.SkewX = size.Width * matrix.Persp1; matrix.TransX = size.Width * (1 - taperFraction); break; case TaperCorner.Both: matrix.SkewX = (size.Width / 2) * matrix.Persp1; matrix.TransX = size.Width * (1 - taperFraction) / 2; break; } break; case TaperSide.Right: matrix.ScaleX = 1 / taperFraction; matrix.Persp0 = (1 - taperFraction) / (size.Width * taperFraction); switch (taperCorner) { case TaperCorner.RightOrBottom: break; case TaperCorner.LeftOrTop: matrix.SkewY = size.Height * matrix.Persp0; break; case TaperCorner.Both: matrix.SkewY = (size.Height / 2) * matrix.Persp0; break; } break; case TaperSide.Bottom: matrix.ScaleY = 1 / taperFraction; matrix.Persp1 = (1 - taperFraction) / (size.Height * taperFraction); switch (taperCorner) { case TaperCorner.RightOrBottom: break; case TaperCorner.LeftOrTop: matrix.SkewX = size.Width * matrix.Persp1; break; case TaperCorner.Both: matrix.SkewX = (size.Width / 2) * matrix.Persp1; break; } break; } return matrix; } } #endif /// /// 3D变换只能支持Skia /// public class ThreeDEffect2 : CPF.Effects.Effect { /// /// -90到90 /// [CPF.PropertyMetadata(0f)] public float X { get { return GetValue(); } set { SetValue(value); } } /// /// -90到90 /// [CPF.PropertyMetadata(0f)] public float Y { get { return GetValue(); } set { SetValue(value); } } /// /// -90到90 /// [CPF.PropertyMetadata(0f)] public float Z { get { return GetValue(); } set { SetValue(value); } } /// /// 默认250 /// [CPF.PropertyMetadata(250f)] public float Depth { get { return GetValue(); } set { SetValue(value); } } /// /// 缩放值 /// [CPF.PropertyMetadata(1f)] public float Scale { get { return GetValue(); } set { SetValue(value); } } public override void DoEffect(DrawingContext dc, Bitmap bitmap) { #if !Net4 // Find center of canvas float xCenter = bitmap.Width / 2; float yCenter = bitmap.Height / 2; // Translate center to origin SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter); // Use 3D matrix for 3D rotations and perspective SKMatrix44 matrix44 = SKMatrix44.CreateIdentity(); matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, X)); matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, Y)); matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, Z)); SKMatrix44 perspectiveMatrix = SKMatrix44.CreateScale(Scale, Scale, Scale); perspectiveMatrix[3, 2] = -1 / Depth; matrix44.PostConcat(perspectiveMatrix); // Concatenate with 2D matrix SKMatrix.PostConcat(ref matrix, matrix44.Matrix); // Translate back to center SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(xCenter, yCenter)); //var tr= dc.Transform; //tr.ScalePrepend(0.9f, 0.9f); //dc.Transform = tr; var canvas = (dc as CPF.Skia.SkiaDrawingContext).SKCanvas; var mat = canvas.TotalMatrix; dc.AntialiasMode = AntialiasMode.AntiAlias; canvas.SetMatrix(mat.PreConcat(matrix)); // Set the matrix and display the bitmap //canvas.SetMatrix(matrix); float xBitmap = xCenter - bitmap.Width / 2; float yBitmap = yCenter - bitmap.Height / 2; canvas.DrawBitmap((bitmap.BitmapImpl as CPF.Skia.SkiaBitmap).Bitmap, xBitmap, yBitmap); #endif } } }