Skip to content

Instantly share code, notes, and snippets.

@equinox2k
Last active October 9, 2019 06:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save equinox2k/a23c5b30365a2edb8ead3c6eb5004019 to your computer and use it in GitHub Desktop.
Save equinox2k/a23c5b30365a2edb8ead3c6eb5004019 to your computer and use it in GitHub Desktop.
SquircleProcessor for ImageSharp
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