Last active
October 9, 2019 06:36
-
-
Save equinox2k/a23c5b30365a2edb8ead3c6eb5004019 to your computer and use it in GitHub Desktop.
SquircleProcessor for ImageSharp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using SixLabors.ImageSharp; | |
using SixLabors.ImageSharp.PixelFormats; | |
using SixLabors.ImageSharp.Processing; | |
using SixLabors.Primitives; | |
using SixLabors.Shapes; | |
namespace EQL.ImageSharp | |
{ | |
public static class SquircleProcessor | |
{ | |
// Example use 4 as factor for iOS 7 style | |
public static IImageProcessingContext ApplySquircle(this IImageProcessingContext ctx, float factor) | |
{ | |
Size size = ctx.GetCurrentSize(); | |
IPathCollection corners = BuildCorners(size.Width, size.Height, factor); | |
var graphicOptions = new GraphicsOptions(true) | |
{ | |
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut | |
}; | |
return ctx.Fill(graphicOptions, Rgba32.Black, corners); | |
} | |
private static PointF CalculateSquirclePoint(float degrees, float radius, SizeF size) | |
{ | |
var theta = (float)(degrees * (Math.PI / 180)); | |
var x = MathF.Pow(MathF.Abs(MathF.Cos(theta)), 2 / radius) * 0.5f * MathF.Sign(MathF.Cos(theta)) + 0.5f; | |
var y = MathF.Pow(MathF.Abs(MathF.Sin(theta)), 2 / radius) * 0.5f * MathF.Sign(MathF.Sin(theta)) + 0.5f; | |
return new PointF(x * size.Width, y * size.Height); | |
} | |
private static IPathCollection BuildCorners(int imageWidth, int imageHeight, float factor) | |
{ | |
factor = MathF.Max(MathF.Min(factor, 100), 0.00000000001f); | |
var size = new SizeF(imageWidth, imageHeight); | |
var points = new List<PointF>(); | |
var maxDimension = Math.Max(imageWidth, imageHeight); | |
for (var i = 0; i < maxDimension; i++) | |
{ | |
var degrees = (360.0f / maxDimension) * i; | |
points.Add(CalculateSquirclePoint(degrees, factor, size)); | |
} | |
var pathBuilder = new PathBuilder(); | |
pathBuilder.AddLines(points.ToArray()); | |
pathBuilder.CloseFigure(); | |
var rect = new RectangularPolygon(0, 0, imageWidth, imageHeight); | |
return new PathCollection(rect.Clip(pathBuilder.Build())); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment