From ff045a13624575d38dd3cf142c074511c8aeb1b1 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Wed, 1 May 2019 22:38:25 +0200 Subject: [PATCH] refactor FilterProcessor stuff --- src/ImageSharp/IImage.cs | 2 +- .../Processing/BlackWhiteExtensions.cs | 12 ++-- src/ImageSharp/Processing/FilterExtensions.cs | 12 ++-- .../Processing/OpacityExtensions.cs | 12 ++-- .../Processors/Filters/BlackWhiteProcessor.cs | 3 +- .../Processors/Filters/FilterProcessor.cs | 43 ++------------- .../Filters/FilterProcessorImplementation.cs | 55 +++++++++++++++++++ .../Processors/Filters/OpacityProcessor.cs | 3 +- .../Transforms/Resize/ResizeProcessor.cs | 7 ++- .../Resize/ResizeProcessorImplementation.cs | 4 -- .../Processors/Transforms/ResizeTests.cs | 1 + 11 files changed, 82 insertions(+), 72 deletions(-) create mode 100644 src/ImageSharp/Processing/Processors/Filters/FilterProcessorImplementation.cs diff --git a/src/ImageSharp/IImage.cs b/src/ImageSharp/IImage.cs index fb251cfd5..b9e2cee61 100644 --- a/src/ImageSharp/IImage.cs +++ b/src/ImageSharp/IImage.cs @@ -4,7 +4,7 @@ using System; namespace SixLabors.ImageSharp -{ +{ /// /// Encapsulates the properties and methods that describe an image. /// diff --git a/src/ImageSharp/Processing/BlackWhiteExtensions.cs b/src/ImageSharp/Processing/BlackWhiteExtensions.cs index 0484fa84e..5dc2341e5 100644 --- a/src/ImageSharp/Processing/BlackWhiteExtensions.cs +++ b/src/ImageSharp/Processing/BlackWhiteExtensions.cs @@ -15,24 +15,20 @@ namespace SixLabors.ImageSharp.Processing /// /// Applies black and white toning to the image. /// - /// The pixel format. /// The image this method extends. /// The . - public static IImageProcessingContext BlackWhite(this IImageProcessingContext source) - where TPixel : struct, IPixel - => source.ApplyProcessor(new BlackWhiteProcessor()); + public static IImageProcessingContext BlackWhite(this IImageProcessingContext source) + => source.ApplyProcessor(new BlackWhiteProcessor()); /// /// Applies black and white toning to the image. /// - /// The pixel format. /// The image this method extends. /// /// The structure that specifies the portion of the image object to alter. /// /// The . - public static IImageProcessingContext BlackWhite(this IImageProcessingContext source, Rectangle rectangle) - where TPixel : struct, IPixel - => source.ApplyProcessor(new BlackWhiteProcessor(), rectangle); + public static IImageProcessingContext BlackWhite(this IImageProcessingContext source, Rectangle rectangle) + => source.ApplyProcessor(new BlackWhiteProcessor(), rectangle); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/FilterExtensions.cs b/src/ImageSharp/Processing/FilterExtensions.cs index 70ac23286..2a1c6bc7f 100644 --- a/src/ImageSharp/Processing/FilterExtensions.cs +++ b/src/ImageSharp/Processing/FilterExtensions.cs @@ -16,26 +16,22 @@ namespace SixLabors.ImageSharp.Processing /// /// Filters an image but the given color matrix /// - /// The pixel format. /// The image this method extends. /// The filter color matrix /// The . - public static IImageProcessingContext Filter(this IImageProcessingContext source, ColorMatrix matrix) - where TPixel : struct, IPixel - => source.ApplyProcessor(new FilterProcessor(matrix)); + public static IImageProcessingContext Filter(this IImageProcessingContext source, ColorMatrix matrix) + => source.ApplyProcessor(new FilterProcessor(matrix)); /// /// Filters an image but the given color matrix /// - /// The pixel format. /// The image this method extends. /// The filter color matrix /// /// The structure that specifies the portion of the image object to alter. /// /// The . - public static IImageProcessingContext Filter(this IImageProcessingContext source, ColorMatrix matrix, Rectangle rectangle) - where TPixel : struct, IPixel - => source.ApplyProcessor(new FilterProcessor(matrix), rectangle); + public static IImageProcessingContext Filter(this IImageProcessingContext source, ColorMatrix matrix, Rectangle rectangle) + => source.ApplyProcessor(new FilterProcessor(matrix), rectangle); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/OpacityExtensions.cs b/src/ImageSharp/Processing/OpacityExtensions.cs index fc3fd331d..6d9198648 100644 --- a/src/ImageSharp/Processing/OpacityExtensions.cs +++ b/src/ImageSharp/Processing/OpacityExtensions.cs @@ -15,26 +15,22 @@ namespace SixLabors.ImageSharp.Processing /// /// Multiplies the alpha component of the image. /// - /// The pixel format. /// The image this method extends. /// The proportion of the conversion. Must be between 0 and 1. /// The . - public static IImageProcessingContext Opacity(this IImageProcessingContext source, float amount) - where TPixel : struct, IPixel - => source.ApplyProcessor(new OpacityProcessor(amount)); + public static IImageProcessingContext Opacity(this IImageProcessingContext source, float amount) + => source.ApplyProcessor(new OpacityProcessor(amount)); /// /// Multiplies the alpha component of the image. /// - /// The pixel format. /// The image this method extends. /// The proportion of the conversion. Must be between 0 and 1. /// /// The structure that specifies the portion of the image object to alter. /// /// The . - public static IImageProcessingContext Opacity(this IImageProcessingContext source, float amount, Rectangle rectangle) - where TPixel : struct, IPixel - => source.ApplyProcessor(new OpacityProcessor(amount), rectangle); + public static IImageProcessingContext Opacity(this IImageProcessingContext source, float amount, Rectangle rectangle) + => source.ApplyProcessor(new OpacityProcessor(amount), rectangle); } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs index 9925ce5c2..8bf925cf0 100644 --- a/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs @@ -9,8 +9,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// Applies a black and white filter matrix to the image /// /// The pixel format. - internal class BlackWhiteProcessor : FilterProcessor - where TPixel : struct, IPixel + internal class BlackWhiteProcessor : FilterProcessor { /// /// Initializes a new instance of the class. diff --git a/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs index dbd843341..3f9f58687 100644 --- a/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs @@ -1,25 +1,15 @@ -// Copyright (c) Six Labors and contributors. +// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; -using System.Numerics; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Primitives; -using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Filters { - /// - /// Provides methods that accept a matrix to apply free-form filters to images. - /// - /// The pixel format. - internal class FilterProcessor : ImageProcessor - where TPixel : struct, IPixel + public class FilterProcessor : IImageProcessor { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The matrix used to apply the image filter public FilterProcessor(ColorMatrix matrix) => this.Matrix = matrix; @@ -29,31 +19,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public ColorMatrix Matrix { get; } - /// - protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) + public IImageProcessor CreatePixelSpecificProcessor() + where TPixel : struct, IPixel { - var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); - int startX = interest.X; - - ColorMatrix matrix = this.Matrix; - - ParallelHelper.IterateRowsWithTempBuffer( - interest, - configuration, - (rows, vectorBuffer) => - { - for (int y = rows.Min; y < rows.Max; y++) - { - Span vectorSpan = vectorBuffer.Span; - int length = vectorSpan.Length; - Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); - PixelOperations.Instance.ToVector4(configuration, rowSpan, vectorSpan); - - Vector4Utils.Transform(vectorSpan, ref matrix); - - PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, rowSpan); - } - }); + return new FilterProcessorImplementation(this); } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Filters/FilterProcessorImplementation.cs b/src/ImageSharp/Processing/Processors/Filters/FilterProcessorImplementation.cs new file mode 100644 index 000000000..1eaaf1ea5 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Filters/FilterProcessorImplementation.cs @@ -0,0 +1,55 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.ParallelUtils; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Primitives; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors.Filters +{ + /// + /// Provides methods that accept a matrix to apply free-form filters to images. + /// + /// The pixel format. + internal class FilterProcessorImplementation : ImageProcessor + where TPixel : struct, IPixel + { + private readonly FilterProcessor paramterSource; + + public FilterProcessorImplementation(FilterProcessor paramterSource) + { + this.paramterSource = paramterSource; + } + + /// + protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) + { + var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); + int startX = interest.X; + + ColorMatrix matrix = this.paramterSource.Matrix; + + ParallelHelper.IterateRowsWithTempBuffer( + interest, + configuration, + (rows, vectorBuffer) => + { + for (int y = rows.Min; y < rows.Max; y++) + { + Span vectorSpan = vectorBuffer.Span; + int length = vectorSpan.Length; + Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); + PixelOperations.Instance.ToVector4(configuration, rowSpan, vectorSpan); + + Vector4Utils.Transform(vectorSpan, ref matrix); + + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, rowSpan); + } + }); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs index 0fea61cad..2d6bf6e83 100644 --- a/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs @@ -9,8 +9,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// Applies an opacity filter matrix using the given amount. /// /// The pixel format. - internal class OpacityProcessor : FilterProcessor - where TPixel : struct, IPixel + internal class OpacityProcessor : FilterProcessor { /// /// Initializes a new instance of the class. diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs index 4348ecdab..d3077b7e6 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs @@ -1,5 +1,5 @@ -// // Copyright (c) Six Labors and contributors. -// // Licensed under the Apache License, Version 2.0. +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. using System; @@ -8,6 +8,9 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms { + // The non-generic processor is responsible for: + // - Encapsulating the parameters of the processor + // - Implementing a factory method to create the pixel-specific processor that contains the implementation public class ResizeProcessor : IImageProcessor { /// diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessorImplementation.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessorImplementation.cs index 6c3db3da7..1a8bb931e 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessorImplementation.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessorImplementation.cs @@ -18,10 +18,6 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms { - // The non-generic processor is responsible for: - // - Encapsulating the parameters of the processor - // - Implementing a factory method to create the pixel-specific processor that contains the implementation - /// /// Provides methods that allow the resizing of images using various algorithms. /// Adapted from diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index c7af8d468..9bf9079d4 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -40,6 +40,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms nameof(KnownResamplers.Lanczos5), }; + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.07F); [Fact]