From a342f8d2b6c4437e4c6c3d7a9d55df4cf2f02213 Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Wed, 17 Aug 2022 18:24:02 +0200 Subject: [PATCH] Add Wave cut effect --- ShareX.HelpersLib/Helpers/ImageHelpers.cs | 87 ++++++++++++++++++- .../Shapes/ShapeManager.cs | 4 +- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/ShareX.HelpersLib/Helpers/ImageHelpers.cs b/ShareX.HelpersLib/Helpers/ImageHelpers.cs index 403785b27..a198b9da7 100644 --- a/ShareX.HelpersLib/Helpers/ImageHelpers.cs +++ b/ShareX.HelpersLib/Helpers/ImageHelpers.cs @@ -237,7 +237,7 @@ private static Bitmap ApplyCutOutEffect(Bitmap bmp, AnchorStyles effectEdge, Cut return TornEdges(bmp, effectSize, effectSize * 2, effectEdge, false); case CutOutEffectType.Wave: - return bmp; + return WavyEdges(bmp, effectSize, effectSize * 5, effectEdge); case CutOutEffectType.Gradient: return bmp; @@ -1664,6 +1664,91 @@ public static void FastBoxBlur(Bitmap bmp, int radius) } } + public static Bitmap WavyEdges(Bitmap bmp, int waveDepth, int waveRange, AnchorStyles sides) + { + if (waveDepth < 1 || waveRange < 1 || sides == AnchorStyles.None) + { + return bmp; + } + + List points = new List(); + + int horizontalWaveCount = Math.Max(2, (bmp.Width / waveRange + 1) / 2 * 2) - 1; + int verticalWaveCount = Math.Max(2, (bmp.Height / waveRange + 1) / 2 * 2) - 1; + + Bitmap updateResult(Bitmap bmpIn, Point[] path) + { + Bitmap bmpResult = bmpIn.CreateEmptyBitmap(); + using (bmpIn) + using (Graphics g = Graphics.FromImage(bmpResult)) + using (TextureBrush brush = new TextureBrush(bmpIn)) + { + g.SetHighQuality(); + g.FillPolygon(brush, path); + } + return bmpResult; + }; + + int waveFunction(int t, int max, int depth) => (int)((1 - Math.Cos(t * Math.PI / max)) * depth / 2); + + if (sides.HasFlag(AnchorStyles.Top) && horizontalWaveCount > 1) + { + waveRange = bmp.Width / horizontalWaveCount; + points.Clear(); + for (int x = 0; x < bmp.Width; x += waveDepth) + { + points.Add(new Point(x, waveFunction(x, waveRange, waveDepth))); + } + points.Add(new Point(bmp.Width - 1, waveFunction(bmp.Width - 1, waveRange, waveDepth))); + points.Add(new Point(bmp.Width - 1, bmp.Height - 1)); + points.Add(new Point(0, bmp.Height - 1)); + bmp = updateResult(bmp, points.ToArray()); + } + + if (sides.HasFlag(AnchorStyles.Right) && verticalWaveCount > 1) + { + waveRange = bmp.Height / verticalWaveCount; + points.Clear(); + points.Add(new Point(0, 0)); + for (int y = 0; y < bmp.Height; y += waveDepth) + { + points.Add(new Point(bmp.Width - 1 - waveDepth + waveFunction(y, waveRange, waveDepth), y)); + } + points.Add(new Point(bmp.Width - 1 - waveDepth + waveFunction(bmp.Height - 1, waveRange, waveDepth), bmp.Height - 1)); + points.Add(new Point(0, bmp.Height - 1)); + bmp = updateResult(bmp, points.ToArray()); + } + + if (sides.HasFlag(AnchorStyles.Bottom) && horizontalWaveCount > 1) + { + waveRange = bmp.Width / horizontalWaveCount; + points.Clear(); + points.Add(new Point(0, 0)); + points.Add(new Point(bmp.Width - 1, 0)); + for (int x = bmp.Width - 1; x >= 0; x -= waveDepth) + { + points.Add(new Point(x, bmp.Height - 1 - waveDepth + waveFunction(x, waveRange, waveDepth))); + } + points.Add(new Point(0, bmp.Height - 1 - waveDepth + waveFunction(0, waveRange, waveDepth))); + bmp = updateResult(bmp, points.ToArray()); + } + + if (sides.HasFlag(AnchorStyles.Left) && verticalWaveCount > 1) + { + waveRange = bmp.Height / verticalWaveCount; + points.Add(new Point(0, 0)); + points.Add(new Point(bmp.Width - 1, 0)); + points.Add(new Point(bmp.Width - 1, bmp.Height - 1)); + for (int y = bmp.Height - 1; y >= 0; y -= waveDepth) + { + points.Add(new Point(waveFunction(y, waveRange, waveDepth), y)); + } + bmp = updateResult(bmp, points.ToArray()); + } + + return bmp; + } + public static Bitmap TornEdges(Bitmap bmp, int tornDepth, int tornRange, AnchorStyles sides, bool curvedEdges) { if (tornDepth < 1 || tornRange < 1 || sides == AnchorStyles.None) diff --git a/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs b/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs index 9199912f8..60723e5fa 100644 --- a/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs +++ b/ShareX.ScreenCaptureLib/Shapes/ShapeManager.cs @@ -1929,12 +1929,12 @@ public void CutOut(RectangleF rect) if (isHorizontal && cropRect.Width > 0) { CollapseAllHorizontal(rect.X, rect.Width); - UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Horizontal, cropRect.X, cropRect.Width, CutOutEffectType.TornEdge, 5)); + UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Horizontal, cropRect.X, cropRect.Width, CutOutEffectType.Wave, 10)); } else if (!isHorizontal && cropRect.Height > 0) { CollapseAllVertical(rect.Y, rect.Height); - UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Vertical, cropRect.Y, cropRect.Height, CutOutEffectType.TornEdge, 5)); + UpdateCanvas(ImageHelpers.CutOutBitmapMiddle(Form.Canvas, Orientation.Vertical, cropRect.Y, cropRect.Height, CutOutEffectType.Wave, 10)); } }