diff --git a/samples/AvatarWithRoundedCorner/Program.cs b/samples/AvatarWithRoundedCorner/Program.cs index 4fa2912c1..39bbfbd66 100644 --- a/samples/AvatarWithRoundedCorner/Program.cs +++ b/samples/AvatarWithRoundedCorner/Program.cs @@ -16,9 +16,9 @@ namespace AvatarWithRoundedCorner using (var img = Image.Load("fb.jpg")) { // as generate returns a new IImage make sure we dispose of it - using (Image dest = img.Clone(x => x.ConvertToAvatar(new Size(200, 200), 20))) + using (Image destRound = img.Clone(x => x.ConvertToAvatar(new Size(200, 200), 20))) { - dest.Save("output/fb.png"); + destRound.Save("output/fb.png"); } using (Image destRound = img.Clone(x => x.ConvertToAvatar(new Size(200, 200), 100))) @@ -30,22 +30,47 @@ namespace AvatarWithRoundedCorner { destRound.Save("output/fb-rounder.png"); } - + + using (Image destRound = img.CloneAndConvertToAvatarWithoutApply(new Size(200, 200), 150)) + { + destRound.Save("output/fb-rounder-without-apply.png"); + } + // the original `img` object has not been altered at all. } } - // lets create our custom image mutating pipeline - private static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext operations, Size size, float cornerRadius) + // 1. The short way: + // Implements a full image mutating pipeline operating on IImageProcessingContext + // We need the dimensions of the resized image to deduce 'IPathCollection' needed to build the corners, + // so we implement an "inline" image processor by utilizing 'ImageExtensions.Apply()' + private static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext processingContext, Size size, float cornerRadius) { - return operations.Resize(new ImageSharp.Processing.ResizeOptions + return processingContext.Resize(new ImageSharp.Processing.ResizeOptions { Size = size, Mode = ImageSharp.Processing.ResizeMode.Crop }).Apply(i => ApplyRoundedCorners(i, cornerRadius)); } - // the combination of `IImageOperations.Run()` + this could be replaced with an `IImageProcessor` + // 2. A more verbose way, avoiding 'Apply()': + // First we create a resized clone of the image, then we draw the corners on that that instance it with Mutate(). + private static Image CloneAndConvertToAvatarWithoutApply(this Image image, Size size, float cornerRadius) + { + Image result = image.Clone( + ctx => ctx.Resize( + new ImageSharp.Processing.ResizeOptions + { + Size = size, + Mode = ImageSharp.Processing.ResizeMode.Crop + })); + + ApplyRoundedCorners(result, cornerRadius); + return result; + } + + // This method can be seen as an inline implementation of an `IImageProcessor`: + // (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`) public static void ApplyRoundedCorners(Image img, float cornerRadius) { IPathCollection corners = BuildCorners(img.Width, img.Height, cornerRadius); diff --git a/src/ImageSharp/Processing/Delegate.cs b/src/ImageSharp/Processing/Delegate.cs index 5edb900df..4b2677c85 100644 --- a/src/ImageSharp/Processing/Delegate.cs +++ b/src/ImageSharp/Processing/Delegate.cs @@ -18,6 +18,8 @@ namespace ImageSharp { /// /// Applies the given operation to the mutable image. + /// Useful when we need to extract information like Width/Height to parameterize the next operation working on the chain. + /// To achieve this the method actually implements an "inline" with as it's processing logic. /// /// The pixel format. /// The image to mutate.