mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-04-04 23:39:26 +08:00
271 lines
8.8 KiB
C#
271 lines
8.8 KiB
C#
using CPF.Drawing;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
#if !Net4
|
|
using SkiaSharp;
|
|
#endif
|
|
|
|
namespace ConsoleApp1
|
|
{
|
|
/// <summary>
|
|
/// 3D变换只能支持Skia
|
|
/// </summary>
|
|
public class ThreeDEffect1 : CPF.Effects.Effect
|
|
{
|
|
/// <summary>
|
|
/// 0到1
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(0.5f)]
|
|
public float Value
|
|
{
|
|
get { return GetValue<float>(); }
|
|
set { SetValue(value); }
|
|
}
|
|
/// <summary>
|
|
/// 翻转方向
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(TaperSide.Left)]
|
|
public TaperSide TaperSide
|
|
{
|
|
get { return GetValue<TaperSide>(); }
|
|
set { SetValue(value); }
|
|
}
|
|
[CPF.PropertyMetadata(TaperCorner.Both)]
|
|
public TaperCorner TaperCorner
|
|
{
|
|
get { return GetValue<TaperCorner>(); }
|
|
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
|
|
|
|
/// <summary>
|
|
/// 3D变换只能支持Skia
|
|
/// </summary>
|
|
public class ThreeDEffect2 : CPF.Effects.Effect
|
|
{
|
|
/// <summary>
|
|
/// -90到90
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(0f)]
|
|
public float X
|
|
{
|
|
get { return GetValue<float>(); }
|
|
set { SetValue(value); }
|
|
}
|
|
/// <summary>
|
|
/// -90到90
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(0f)]
|
|
public float Y
|
|
{
|
|
get { return GetValue<float>(); }
|
|
set { SetValue(value); }
|
|
}
|
|
/// <summary>
|
|
/// -90到90
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(0f)]
|
|
public float Z
|
|
{
|
|
get { return GetValue<float>(); }
|
|
set { SetValue(value); }
|
|
}
|
|
/// <summary>
|
|
/// 默认250
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(250f)]
|
|
public float Depth
|
|
{
|
|
get { return GetValue<float>(); }
|
|
set { SetValue(value); }
|
|
}
|
|
/// <summary>
|
|
/// 缩放值
|
|
/// </summary>
|
|
[CPF.PropertyMetadata(1f)]
|
|
public float Scale
|
|
{
|
|
get { return GetValue<float>(); }
|
|
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
|
|
}
|
|
}
|
|
|
|
}
|