diff --git a/src/ImageProcessorCore/Filters/Alpha.cs b/src/ImageProcessorCore/Filters/Alpha.cs index 738336def3..3532bb675d 100644 --- a/src/ImageProcessorCore/Filters/Alpha.cs +++ b/src/ImageProcessorCore/Filters/Alpha.cs @@ -1,68 +1,51 @@ // // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System; - using System.Numerics; - using System.Threading.Tasks; + using Processors; /// - /// An to change the Alpha of an . + /// Extension methods for the type. /// - public class Alpha : ParallelImageProcessor + public static partial class ImageExtensions { /// - /// Initializes a new instance of the class. + /// Alters the alpha component of the image. /// - /// The percentage to adjust the opacity of the image. Must be between 0 and 100. - /// - /// is less than 0 or is greater than 100. - /// - public Alpha(int percent) + /// The image this method extends. + /// The new opacity of the image. Must be between 0 and 100. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Alpha(this Image source, int percent, ProgressEventHandler progressHandler = null) { - Guard.MustBeBetweenOrEqualTo(percent, 0, 100, nameof(percent)); - this.Value = percent; + return Alpha(source, percent, source.Bounds, progressHandler); } /// - /// Gets the alpha value. + /// Alters the alpha component of the image. /// - public int Value { get; } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + /// The image this method extends. + /// The new opacity of the image. Must be between 0 and 100. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Alpha(this Image source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) { - float alpha = this.Value / 100f; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; - Vector4 alphaVector = new Vector4(1, 1, 1, alpha); + AlphaProcessor processor = new AlphaProcessor(percent); + processor.OnProgress += progressHandler; - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + try { - Parallel.For( - startY, - endY, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x++) - { - Vector4 color = Color.ToNonPremultiplied(sourcePixels[x, y]).ToVector4(); - color *= alphaVector; - targetPixels[x, y] = Color.FromNonPremultiplied(new Color(color)); - } - - this.OnRowProcessed(); - } - }); - + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/BackgroundColor.cs b/src/ImageProcessorCore/Filters/BackgroundColor.cs index c8fa2f4e9f..98709cb32c 100644 --- a/src/ImageProcessorCore/Filters/BackgroundColor.cs +++ b/src/ImageProcessorCore/Filters/BackgroundColor.cs @@ -1,77 +1,36 @@ // // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System; - using System.Threading.Tasks; + using Processors; /// - /// Sets the background color of the image. + /// Extension methods for the type. /// - public class BackgroundColor : ParallelImageProcessor + public static partial class ImageExtensions { /// - /// The epsilon for comparing floating point numbers. + /// Combines the given image together with the current one by blending their pixels. /// - private const float Epsilon = 0.001f; - - /// - /// Initializes a new instance of the class. - /// - /// The to set the background color to. - public BackgroundColor(Color color) + /// The image this method extends. + /// The color to set as the background. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image BackgroundColor(this Image source, Color color, ProgressEventHandler progressHandler = null) { - this.Value = Color.FromNonPremultiplied(color); - } + BackgroundColorProcessor processor = new BackgroundColorProcessor(color); + processor.OnProgress += progressHandler; - /// - /// Gets the background color value. - /// - public Color Value { get; } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - { - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; - Color backgroundColor = this.Value; - - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + try { - Parallel.For( - startY, - endY, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x++) - { - Color color = sourcePixels[x, y]; - float a = color.A; - - if (a < 1 && a > 0) - { - color = Color.Lerp(color, backgroundColor, .5f); - } - - if (Math.Abs(a) < Epsilon) - { - color = backgroundColor; - } - - targetPixels[x, y] = color; - } - - this.OnRowProcessed(); - } - }); + return source.Process(source.Bounds, processor); + } + finally + { + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/BlackWhite.cs b/src/ImageProcessorCore/Filters/BlackWhite.cs new file mode 100644 index 0000000000..98c3b7744a --- /dev/null +++ b/src/ImageProcessorCore/Filters/BlackWhite.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies black and white toning to the image. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image BlackWhite(this Image source, ProgressEventHandler progressHandler = null) + { + return BlackWhite(source, source.Bounds, progressHandler); + } + + /// + /// Applies black and white toning to the image. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image BlackWhite(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + BlackWhiteProcessor processor = new BlackWhiteProcessor(); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Blend.cs b/src/ImageProcessorCore/Filters/Blend.cs index 4b886cf3bc..77a94e3fa3 100644 --- a/src/ImageProcessorCore/Filters/Blend.cs +++ b/src/ImageProcessorCore/Filters/Blend.cs @@ -1,85 +1,59 @@ // // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System.Threading.Tasks; + using Processors; /// - /// Combines two images together by blending the pixels. + /// Extension methods for the type. /// - public class Blend : ParallelImageProcessor + public static partial class ImageExtensions { /// - /// The image to blend. - /// - private readonly ImageBase blend; - - /// - /// Initializes a new instance of the class. + /// Combines the given image together with the current one by blending their pixels. /// + /// The image this method extends. /// /// The image to blend with the currently processing image. /// Disposal of this image is the responsibility of the developer. /// - /// The opacity of the image to blend. Between 0 and 100. - public Blend(ImageBase image, int alpha = 100) + /// The opacity of the image image to blend. Must be between 0 and 100. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Blend(this Image source, ImageBase image, int percent = 50, ProgressEventHandler progressHandler = null) { - Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha)); - this.blend = image; - this.Value = alpha; + return Blend(source, image, percent, source.Bounds, progressHandler); } /// - /// Gets the alpha percentage value. + /// Combines the given image together with the current one by blending their pixels. /// - public int Value { get; } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + /// The image this method extends. + /// + /// The image to blend with the currently processing image. + /// Disposal of this image is the responsibility of the developer. + /// + /// The opacity of the image image to blend. Must be between 0 and 100. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Blend(this Image source, ImageBase image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) { - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; - Rectangle bounds = this.blend.Bounds; - float alpha = this.Value / 100f; + BlendProcessor processor = new BlendProcessor(image, percent); + processor.OnProgress += progressHandler; - using (PixelAccessor toBlendPixels = this.blend.Lock()) - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + try { - Parallel.For( - startY, - endY, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x++) - { - Color color = sourcePixels[x, y]; - - if (bounds.Contains(x, y)) - { - Color blendedColor = toBlendPixels[x, y]; - - if (blendedColor.A > 0) - { - // Lerping colors is dependent on the alpha of the blended color - float alphaFactor = alpha > 0 ? alpha : blendedColor.A; - color = Color.Lerp(color, blendedColor, alphaFactor); - } - } - - targetPixels[x, y] = color; - } - - this.OnRowProcessed(); - } - }); + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/BoxBlur.cs b/src/ImageProcessorCore/Filters/BoxBlur.cs new file mode 100644 index 0000000000..474f0d6e77 --- /dev/null +++ b/src/ImageProcessorCore/Filters/BoxBlur.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies a box blur to the image. + /// + /// The image this method extends. + /// The 'radius' value representing the size of the area to sample. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image BoxBlur(this Image source, int radius = 7, ProgressEventHandler progressHandler = null) + { + return BoxBlur(source, radius, source.Bounds, progressHandler); + } + + /// + /// Applies a box blur to the image. + /// + /// The image this method extends. + /// The 'radius' value representing the size of the area to sample. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image BoxBlur(this Image source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + BoxBlurProcessor processor = new BoxBlurProcessor(radius); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Brightness.cs b/src/ImageProcessorCore/Filters/Brightness.cs index 7bc3c35a09..52944c8010 100644 --- a/src/ImageProcessorCore/Filters/Brightness.cs +++ b/src/ImageProcessorCore/Filters/Brightness.cs @@ -1,68 +1,51 @@ // // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System; - using System.Numerics; - using System.Threading.Tasks; + using Processors; /// - /// An to change the brightness of an . + /// Extension methods for the type. /// - public class Brightness : ParallelImageProcessor + public static partial class ImageExtensions { /// - /// Initializes a new instance of the class. + /// Alters the brightness component of the image. /// - /// The new brightness of the image. Must be between -100 and 100. - /// - /// is less than -100 or is greater than 100. - /// - public Brightness(int brightness) + /// The image this method extends. + /// The new brightness of the image. Must be between -100 and 100. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Brightness(this Image source, int amount, ProgressEventHandler progressHandler = null) { - Guard.MustBeBetweenOrEqualTo(brightness, -100, 100, nameof(brightness)); - this.Value = brightness; + return Brightness(source, amount, source.Bounds, progressHandler); } /// - /// Gets the brightness value. + /// Alters the brightness component of the image. /// - public int Value { get; } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + /// The image this method extends. + /// The new brightness of the image. Must be between -100 and 100. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Brightness(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) { - float brightness = this.Value / 100f; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; + BrightnessProcessor processor = new BrightnessProcessor(amount); + processor.OnProgress += progressHandler; - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + try { - Parallel.For( - startY, - endY, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x++) - { - Color color = Color.Expand(sourcePixels[x, y]); - - Vector3 vector3 = color.ToVector3(); - vector3 += new Vector3(brightness); - - targetPixels[x, y] = Color.Compress(new Color(vector3, color.A)); - } - this.OnRowProcessed(); - } - }); + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/ColorBlindness.cs b/src/ImageProcessorCore/Filters/ColorBlindness.cs new file mode 100644 index 0000000000..78267b05e3 --- /dev/null +++ b/src/ImageProcessorCore/Filters/ColorBlindness.cs @@ -0,0 +1,88 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies the given colorblindness simulator to the image. + /// + /// The image this method extends. + /// The type of color blindness simulator to apply. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null) + { + return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler); + } + + /// + /// Applies the given colorblindness simulator to the image. + /// + /// The image this method extends. + /// The type of color blindness simulator to apply. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + IImageProcessor processor; + + switch (colorBlindness) + { + case ImageProcessorCore.ColorBlindness.Achromatomaly: + processor = new AchromatomalyProcessor(); + break; + + case ImageProcessorCore.ColorBlindness.Achromatopsia: + processor = new AchromatopsiaProcessor(); + break; + + case ImageProcessorCore.ColorBlindness.Deuteranomaly: + processor = new DeuteranomalyProcessor(); + break; + + case ImageProcessorCore.ColorBlindness.Deuteranopia: + processor = new DeuteranopiaProcessor(); + break; + + case ImageProcessorCore.ColorBlindness.Protanomaly: + processor = new ProtanomalyProcessor(); + break; + + case ImageProcessorCore.ColorBlindness.Protanopia: + processor = new ProtanopiaProcessor(); + break; + + case ImageProcessorCore.ColorBlindness.Tritanomaly: + processor = new TritanomalyProcessor(); + break; + + default: + processor = new TritanopiaProcessor(); + break; + } + + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Contrast.cs b/src/ImageProcessorCore/Filters/Contrast.cs index eeaa51ec12..cab12ca4e5 100644 --- a/src/ImageProcessorCore/Filters/Contrast.cs +++ b/src/ImageProcessorCore/Filters/Contrast.cs @@ -1,69 +1,51 @@ // // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System; - using System.Numerics; - using System.Threading.Tasks; + using Processors; /// - /// An to change the contrast of an . + /// Extension methods for the type. /// - public class Contrast : ParallelImageProcessor + public static partial class ImageExtensions { /// - /// Initializes a new instance of the class. + /// Alters the contrast component of the image. /// - /// The new contrast of the image. Must be between -100 and 100. - /// - /// is less than -100 or is greater than 100. - /// - public Contrast(int contrast) + /// The image this method extends. + /// The new contrast of the image. Must be between -100 and 100. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Contrast(this Image source, int amount, ProgressEventHandler progressHandler = null) { - Guard.MustBeBetweenOrEqualTo(contrast, -100, 100, nameof(contrast)); - this.Value = contrast; + return Contrast(source, amount, source.Bounds, progressHandler); } /// - /// Gets the contrast value. + /// Alters the contrast component of the image. /// - public int Value { get; } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + /// The image this method extends. + /// The new contrast of the image. Must be between -100 and 100. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Contrast(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) { - float contrast = (100f + this.Value) / 100f; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; - Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1); - Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1); + ContrastProcessor processor = new ContrastProcessor(amount); + processor.OnProgress += progressHandler; - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + try + { + return source.Process(rectangle, processor); + } + finally { - Parallel.For( - startY, - endY, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x++) - { - Vector4 color = Color.Expand(sourcePixels[x, y]).ToVector4(); - color -= shiftVector; - color *= contrastVector; - color += shiftVector; - targetPixels[x, y] = Color.Compress(new Color(color)); - } - this.OnRowProcessed(); - } - }); + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/DetectEdges.cs b/src/ImageProcessorCore/Filters/DetectEdges.cs new file mode 100644 index 0000000000..ac3a0282d5 --- /dev/null +++ b/src/ImageProcessorCore/Filters/DetectEdges.cs @@ -0,0 +1,63 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Detects any edges within the image. Uses the filter + /// operating in greyscale mode. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image DetectEdges(this Image source, ProgressEventHandler progressHandler = null) + { + return DetectEdges(source, source.Bounds, new SobelProcessor { Greyscale = true }, progressHandler); + } + + /// + /// Detects any edges within the image. + /// + /// The image this method extends. + /// The filter for detecting edges. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image DetectEdges(this Image source, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) + { + return DetectEdges(source, source.Bounds, filter, progressHandler); + } + + /// + /// Detects any edges within the image. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The filter for detecting edges. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image DetectEdges(this Image source, Rectangle rectangle, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) + { + filter.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, filter); + } + finally + { + filter.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Greyscale.cs b/src/ImageProcessorCore/Filters/Greyscale.cs new file mode 100644 index 0000000000..786a935766 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Greyscale.cs @@ -0,0 +1,55 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies greyscale toning to the image. + /// + /// The image this method extends. + /// The formula to apply to perform the operation. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) + { + return Greyscale(source, source.Bounds, mode, progressHandler); + } + + /// + /// Applies greyscale toning to the image. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The formula to apply to perform the operation. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) + { + IImageProcessor processor = mode == GreyscaleMode.Bt709 + ? (IImageProcessor)new GreyscaleBt709Processor() + : new GreyscaleBt601Processor(); + + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/GuassianBlur.cs b/src/ImageProcessorCore/Filters/GuassianBlur.cs new file mode 100644 index 0000000000..646c6bdc08 --- /dev/null +++ b/src/ImageProcessorCore/Filters/GuassianBlur.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies a Guassian blur to the image. + /// + /// The image this method extends. + /// The 'sigma' value representing the weight of the blur. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image GuassianBlur(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) + { + return GuassianBlur(source, sigma, source.Bounds, progressHandler); + } + + /// + /// Applies a Guassian blur to the image. + /// + /// The image this method extends. + /// The 'sigma' value representing the weight of the blur. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + GuassianBlurProcessor processor = new GuassianBlurProcessor(sigma); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/GuassianSharpen.cs b/src/ImageProcessorCore/Filters/GuassianSharpen.cs new file mode 100644 index 0000000000..06993070d8 --- /dev/null +++ b/src/ImageProcessorCore/Filters/GuassianSharpen.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies a Guassian sharpening filter to the image. + /// + /// The image this method extends. + /// The 'sigma' value representing the weight of the blur. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image GuassianSharpen(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) + { + return GuassianSharpen(source, sigma, source.Bounds, progressHandler); + } + + /// + /// Applies a Guassian sharpening filter to the image. + /// + /// The image this method extends. + /// The 'sigma' value representing the weight of the blur. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + GuassianSharpenProcessor processor = new GuassianSharpenProcessor(sigma); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Hue.cs b/src/ImageProcessorCore/Filters/Hue.cs new file mode 100644 index 0000000000..45a995c301 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Hue.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Alters the hue component of the image. + /// + /// The image this method extends. + /// The angle in degrees to adjust the image. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Hue(this Image source, float degrees, ProgressEventHandler progressHandler = null) + { + return Hue(source, degrees, source.Bounds, progressHandler); + } + + /// + /// Alters the hue component of the image. + /// + /// The image this method extends. + /// The angle in degrees to adjust the image. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Hue(this Image source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + HueProcessor processor = new HueProcessor(degrees); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/ImageFilterExtensions.cs b/src/ImageProcessorCore/Filters/ImageFilterExtensions.cs deleted file mode 100644 index b0baffa2c6..0000000000 --- a/src/ImageProcessorCore/Filters/ImageFilterExtensions.cs +++ /dev/null @@ -1,784 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageProcessorCore.Filters -{ - /// - /// Extensions methods for to apply filters to the image. - /// - public static class ImageFilterExtensions - { - /// - /// Alters the alpha component of the image. - /// - /// The image this method extends. - /// The new opacity of the image. Must be between 0 and 100. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Alpha(this Image source, int percent, ProgressEventHandler progressHandler = null) - { - return Alpha(source, percent, source.Bounds, progressHandler); - } - - /// - /// Alters the alpha component of the image. - /// - /// The image this method extends. - /// The new opacity of the image. Must be between 0 and 100. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Alpha(this Image source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Alpha processor = new Alpha(percent); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Combines the given image together with the current one by blending their pixels. - /// - /// The image this method extends. - /// The color to set as the background. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image BackgroundColor(this Image source, Color color, ProgressEventHandler progressHandler = null) - { - BackgroundColor processor = new BackgroundColor(color); - processor.OnProgress += progressHandler; - - try - { - return source.Process(source.Bounds, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Combines the given image together with the current one by blending their pixels. - /// - /// The image this method extends. - /// - /// The image to blend with the currently processing image. - /// Disposal of this image is the responsibility of the developer. - /// - /// The opacity of the image image to blend. Must be between 0 and 100. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Blend(this Image source, ImageBase image, int percent = 50, ProgressEventHandler progressHandler = null) - { - return Blend(source, image, percent, source.Bounds, progressHandler); - } - - /// - /// Combines the given image together with the current one by blending their pixels. - /// - /// The image this method extends. - /// - /// The image to blend with the currently processing image. - /// Disposal of this image is the responsibility of the developer. - /// - /// The opacity of the image image to blend. Must be between 0 and 100. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Blend(this Image source, ImageBase image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Blend processor = new Blend(image, percent); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Applies black and white toning to the image. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image BlackWhite(this Image source, ProgressEventHandler progressHandler = null) - { - return BlackWhite(source, source.Bounds, progressHandler); - } - - /// - /// Applies black and white toning to the image. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image BlackWhite(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - BlackWhite processor = new BlackWhite(); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Applies a box blur to the image. - /// - /// The image this method extends. - /// The 'radius' value representing the size of the area to sample. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image BoxBlur(this Image source, int radius = 7, ProgressEventHandler progressHandler = null) - { - return BoxBlur(source, radius, source.Bounds, progressHandler); - } - - /// - /// Applies a box blur to the image. - /// - /// The image this method extends. - /// The 'radius' value representing the size of the area to sample. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image BoxBlur(this Image source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - BoxBlur processor = new BoxBlur(radius); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the brightness component of the image. - /// - /// The image this method extends. - /// The new brightness of the image. Must be between -100 and 100. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Brightness(this Image source, int amount, ProgressEventHandler progressHandler = null) - { - return Brightness(source, amount, source.Bounds, progressHandler); - } - - /// - /// Alters the brightness component of the image. - /// - /// The image this method extends. - /// The new brightness of the image. Must be between -100 and 100. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Brightness(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Brightness processor = new Brightness(amount); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Applies the given colorblindness simulator to the image. - /// - /// The image this method extends. - /// The type of color blindness simulator to apply. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null) - { - return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler); - } - - /// - /// Applies the given colorblindness simulator to the image. - /// - /// The image this method extends. - /// The type of color blindness simulator to apply. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - IImageProcessor processor; - - switch (colorBlindness) - { - case Filters.ColorBlindness.Achromatomaly: - processor = new Achromatomaly(); - break; - - case Filters.ColorBlindness.Achromatopsia: - processor = new Achromatopsia(); - break; - - case Filters.ColorBlindness.Deuteranomaly: - processor = new Deuteranomaly(); - break; - - case Filters.ColorBlindness.Deuteranopia: - processor = new Deuteranopia(); - break; - - case Filters.ColorBlindness.Protanomaly: - processor = new Protanomaly(); - break; - - case Filters.ColorBlindness.Protanopia: - processor = new Protanopia(); - break; - - case Filters.ColorBlindness.Tritanomaly: - processor = new Tritanomaly(); - break; - - default: - processor = new Tritanopia(); - break; - } - - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the contrast component of the image. - /// - /// The image this method extends. - /// The new contrast of the image. Must be between -100 and 100. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Contrast(this Image source, int amount, ProgressEventHandler progressHandler = null) - { - return Contrast(source, amount, source.Bounds, progressHandler); - } - - /// - /// Alters the contrast component of the image. - /// - /// The image this method extends. - /// The new contrast of the image. Must be between -100 and 100. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Contrast(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Contrast processor = new Contrast(amount); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Detects any edges within the image. Uses the filter - /// operating in greyscale mode. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image DetectEdges(this Image source, ProgressEventHandler progressHandler = null) - { - return DetectEdges(source, source.Bounds, new Sobel { Greyscale = true }, progressHandler); - } - - /// - /// Detects any edges within the image. - /// - /// The image this method extends. - /// The filter for detecting edges. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image DetectEdges(this Image source, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) - { - return DetectEdges(source, source.Bounds, filter, progressHandler); - } - - /// - /// Detects any edges within the image. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// The filter for detecting edges. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image DetectEdges(this Image source, Rectangle rectangle, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) - { - filter.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, filter); - } - finally - { - filter.OnProgress -= progressHandler; - } - } - - /// - /// Applies greyscale toning to the image. - /// - /// The image this method extends. - /// The formula to apply to perform the operation. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) - { - return Greyscale(source, source.Bounds, mode, progressHandler); - } - - /// - /// Applies greyscale toning to the image. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// The formula to apply to perform the operation. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) - { - IImageProcessor processor = mode == GreyscaleMode.Bt709 - ? (IImageProcessor)new GreyscaleBt709() - : new GreyscaleBt601(); - - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Applies a Guassian blur to the image. - /// - /// The image this method extends. - /// The 'sigma' value representing the weight of the blur. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image GuassianBlur(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) - { - return GuassianBlur(source, sigma, source.Bounds, progressHandler); - } - - /// - /// Applies a Guassian blur to the image. - /// - /// The image this method extends. - /// The 'sigma' value representing the weight of the blur. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - GuassianBlur processor = new GuassianBlur(sigma); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Applies a Guassian sharpening filter to the image. - /// - /// The image this method extends. - /// The 'sigma' value representing the weight of the blur. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image GuassianSharpen(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) - { - return GuassianSharpen(source, sigma, source.Bounds, progressHandler); - } - - /// - /// Applies a Guassian sharpening filter to the image. - /// - /// The image this method extends. - /// The 'sigma' value representing the weight of the blur. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - GuassianSharpen processor = new GuassianSharpen(sigma); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the hue component of the image. - /// - /// The image this method extends. - /// The angle in degrees to adjust the image. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Hue(this Image source, float degrees, ProgressEventHandler progressHandler = null) - { - return Hue(source, degrees, source.Bounds, progressHandler); - } - - /// - /// Alters the hue component of the image. - /// - /// The image this method extends. - /// The angle in degrees to adjust the image. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Hue(this Image source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Hue processor = new Hue(degrees); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Inverts the colors of the image. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Invert(this Image source, ProgressEventHandler progressHandler = null) - { - return Invert(source, source.Bounds, progressHandler); - } - - /// - /// Inverts the colors of the image. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Invert(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Invert processor = new Invert(); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the colors of the image recreating an old Kodachrome camera effect. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Kodachrome(this Image source, ProgressEventHandler progressHandler = null) - { - return Kodachrome(source, source.Bounds, progressHandler); - } - - /// - /// Alters the colors of the image recreating an old Kodachrome camera effect. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Kodachrome(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Kodachrome processor = new Kodachrome(); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the colors of the image recreating an old Lomograph camera effect. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Lomograph(this Image source, ProgressEventHandler progressHandler = null) - { - return Lomograph(source, source.Bounds, progressHandler); - } - - /// - /// Alters the colors of the image recreating an old Lomograph camera effect. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Lomograph(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Lomograph processor = new Lomograph(); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the colors of the image recreating an old Polaroid camera effect. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Polaroid(this Image source, ProgressEventHandler progressHandler = null) - { - return Polaroid(source, source.Bounds, progressHandler); - } - - /// - /// Alters the colors of the image recreating an old Polaroid camera effect. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Polaroid(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Polaroid processor = new Polaroid(); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Pixelates and image with the given pixel size. - /// - /// The image this method extends. - /// The size of the pixels. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Pixelate(this Image source, int size = 4, ProgressEventHandler progressHandler = null) - { - return Pixelate(source, size, source.Bounds, progressHandler); - } - - /// - /// Pixelates and image with the given pixel size. - /// - /// The image this method extends. - /// The size of the pixels. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Pixelate(this Image source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Pixelate processor = new Pixelate(size); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Alters the saturation component of the image. - /// - /// The image this method extends. - /// The new saturation of the image. Must be between -100 and 100. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Saturation(this Image source, int amount, ProgressEventHandler progressHandler = null) - { - return Saturation(source, amount, source.Bounds, progressHandler); - } - - /// - /// Alters the saturation component of the image. - /// - /// The image this method extends. - /// The new saturation of the image. Must be between -100 and 100. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Saturation(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Saturation processor = new Saturation(amount); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - - /// - /// Applies sepia toning to the image. - /// - /// The image this method extends. - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Sepia(this Image source, ProgressEventHandler progressHandler = null) - { - return Sepia(source, source.Bounds, progressHandler); - } - - /// - /// Applies sepia toning to the image. - /// - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// A delegate which is called as progress is made processing the image. - /// The . - public static Image Sepia(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) - { - Sepia processor = new Sepia(); - processor.OnProgress += progressHandler; - - try - { - return source.Process(rectangle, processor); - } - finally - { - processor.OnProgress -= progressHandler; - } - } - } -} diff --git a/src/ImageProcessorCore/Filters/Invert.cs b/src/ImageProcessorCore/Filters/Invert.cs index 3399d99598..eaeddfc62b 100644 --- a/src/ImageProcessorCore/Filters/Invert.cs +++ b/src/ImageProcessorCore/Filters/Invert.cs @@ -1,47 +1,49 @@ // // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System.Numerics; - using System.Threading.Tasks; + using Processors; /// - /// An to invert the colors of an . + /// Extension methods for the type. /// - public class Invert : ParallelImageProcessor + public static partial class ImageExtensions { - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + /// + /// Inverts the colors of the image. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Invert(this Image source, ProgressEventHandler progressHandler = null) { - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; - Vector3 inverseVector = Vector3.One; + return Invert(source, source.Bounds, progressHandler); + } - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) - { - Parallel.For( - startY, - endY, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x++) - { - Color color = sourcePixels[x, y]; - Vector3 vector = inverseVector - color.ToVector3(); - targetPixels[x, y] = new Color(vector, color.A); - } + /// + /// Inverts the colors of the image. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Invert(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + InvertProcessor processor = new InvertProcessor(); + processor.OnProgress += progressHandler; - this.OnRowProcessed(); - } - }); + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/Kodachrome.cs b/src/ImageProcessorCore/Filters/Kodachrome.cs new file mode 100644 index 0000000000..3b4e3f1c66 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Kodachrome.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Alters the colors of the image recreating an old Kodachrome camera effect. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Kodachrome(this Image source, ProgressEventHandler progressHandler = null) + { + return Kodachrome(source, source.Bounds, progressHandler); + } + + /// + /// Alters the colors of the image recreating an old Kodachrome camera effect. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Kodachrome(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + KodachromeProcessor processor = new KodachromeProcessor(); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Lomograph.cs b/src/ImageProcessorCore/Filters/Lomograph.cs new file mode 100644 index 0000000000..5ecf0bcf4a --- /dev/null +++ b/src/ImageProcessorCore/Filters/Lomograph.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Alters the colors of the image recreating an old Lomograph camera effect. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Lomograph(this Image source, ProgressEventHandler progressHandler = null) + { + return Lomograph(source, source.Bounds, progressHandler); + } + + /// + /// Alters the colors of the image recreating an old Lomograph camera effect. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Lomograph(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + LomographProcessor processor = new LomographProcessor(); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/ColorBlindness.cs b/src/ImageProcessorCore/Filters/Options/ColorBlindness.cs similarity index 96% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/ColorBlindness.cs rename to src/ImageProcessorCore/Filters/Options/ColorBlindness.cs index 7416a42d2b..6d7fe849bc 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/ColorBlindness.cs +++ b/src/ImageProcessorCore/Filters/Options/ColorBlindness.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { /// /// Enumerates the various types of color blindness. diff --git a/src/ImageProcessorCore/Filters/Pixelate.cs b/src/ImageProcessorCore/Filters/Pixelate.cs index 3a076a912c..6f86848d6a 100644 --- a/src/ImageProcessorCore/Filters/Pixelate.cs +++ b/src/ImageProcessorCore/Filters/Pixelate.cs @@ -1,96 +1,51 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. -// +// ------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore { - using System; - using System.Collections.Generic; - using System.Threading.Tasks; + using Processors; /// - /// An to invert the colors of an . + /// Extension methods for the type. /// - public class Pixelate : ParallelImageProcessor + public static partial class ImageExtensions { /// - /// Initializes a new instance of the class. + /// Pixelates and image with the given pixel size. /// - /// The size of the pixels. Must be greater than 0. - /// - /// is less than 0 or equal to 0. - /// - public Pixelate(int size) + /// The image this method extends. + /// The size of the pixels. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Pixelate(this Image source, int size = 4, ProgressEventHandler progressHandler = null) { - Guard.MustBeGreaterThan(size, 0, nameof(size)); - this.Value = size; + return Pixelate(source, size, source.Bounds, progressHandler); } - /// - public override int Parallelism { get; set; } = 1; - /// - /// Gets or the pixel size. + /// Pixelates and image with the given pixel size. /// - public int Value { get; } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + /// The image this method extends. + /// The size of the pixels. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Pixelate(this Image source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null) { - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; - int startX = sourceRectangle.X; - int endX = sourceRectangle.Right; - int size = this.Value; - int offset = this.Value / 2; - - // Get the range on the y-plane to choose from. - IEnumerable range = EnumerableExtensions.SteppedRange(startY, i => i < endY, size); + PixelateProcessor processor = new PixelateProcessor(size); + processor.OnProgress += progressHandler; - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + try { - Parallel.ForEach( - range, - y => - { - if (y >= sourceY && y < sourceBottom) - { - for (int x = startX; x < endX; x += size) - { - - int offsetX = offset; - int offsetY = offset; - - // Make sure that the offset is within the boundary of the - // image. - while (y + offsetY >= sourceBottom) - { - offsetY--; - } - - while (x + offsetX >= endX) - { - offsetX--; - } - - // Get the pixel color in the centre of the soon to be pixelated area. - // ReSharper disable AccessToDisposedClosure - Color pixel = sourcePixels[x + offsetX, y + offsetY]; - - // For each pixel in the pixelate size, set it to the centre color. - for (int l = y; l < y + size && l < sourceBottom; l++) - { - for (int k = x; k < x + size && k < endX; k++) - { - targetPixels[k, l] = pixel; - } - } - } - this.OnRowProcessed(); - } - }); + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; } } } diff --git a/src/ImageProcessorCore/Filters/Polaroid.cs b/src/ImageProcessorCore/Filters/Polaroid.cs new file mode 100644 index 0000000000..165f1d59a5 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Polaroid.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Alters the colors of the image recreating an old Polaroid camera effect. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Polaroid(this Image source, ProgressEventHandler progressHandler = null) + { + return Polaroid(source, source.Bounds, progressHandler); + } + + /// + /// Alters the colors of the image recreating an old Polaroid camera effect. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Polaroid(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + PolaroidProcessor processor = new PolaroidProcessor(); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Processors/AlphaProcessor.cs b/src/ImageProcessorCore/Filters/Processors/AlphaProcessor.cs new file mode 100644 index 0000000000..72ba79f9b3 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/AlphaProcessor.cs @@ -0,0 +1,69 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System; + using System.Numerics; + using System.Threading.Tasks; + + /// + /// An to change the Alpha of an . + /// + public class AlphaProcessor : ParallelImageProcessor + { + /// + /// Initializes a new instance of the class. + /// + /// The percentage to adjust the opacity of the image. Must be between 0 and 100. + /// + /// is less than 0 or is greater than 100. + /// + public AlphaProcessor(int percent) + { + Guard.MustBeBetweenOrEqualTo(percent, 0, 100, nameof(percent)); + this.Value = percent; + } + + /// + /// Gets the alpha value. + /// + public int Value { get; } + + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + float alpha = this.Value / 100f; + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + Vector4 alphaVector = new Vector4(1, 1, 1, alpha); + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + startY, + endY, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x++) + { + Vector4 color = Color.ToNonPremultiplied(sourcePixels[x, y]).ToVector4(); + color *= alphaVector; + targetPixels[x, y] = Color.FromNonPremultiplied(new Color(color)); + } + + this.OnRowProcessed(); + } + }); + + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Processors/BackgroundColorProcessor.cs b/src/ImageProcessorCore/Filters/Processors/BackgroundColorProcessor.cs new file mode 100644 index 0000000000..ef451a89d3 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/BackgroundColorProcessor.cs @@ -0,0 +1,78 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System; + using System.Threading.Tasks; + + /// + /// Sets the background color of the image. + /// + public class BackgroundColorProcessor : ParallelImageProcessor + { + /// + /// The epsilon for comparing floating point numbers. + /// + private const float Epsilon = 0.001f; + + /// + /// Initializes a new instance of the class. + /// + /// The to set the background color to. + public BackgroundColorProcessor(Color color) + { + this.Value = Color.FromNonPremultiplied(color); + } + + /// + /// Gets the background color value. + /// + public Color Value { get; } + + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + Color backgroundColor = this.Value; + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + startY, + endY, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x++) + { + Color color = sourcePixels[x, y]; + float a = color.A; + + if (a < 1 && a > 0) + { + color = Color.Lerp(color, backgroundColor, .5f); + } + + if (Math.Abs(a) < Epsilon) + { + color = backgroundColor; + } + + targetPixels[x, y] = color; + } + + this.OnRowProcessed(); + } + }); + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Binarization/Threshold.cs b/src/ImageProcessorCore/Filters/Processors/Binarization/ThresholdProcessor.cs similarity index 89% rename from src/ImageProcessorCore/Filters/Binarization/Threshold.cs rename to src/ImageProcessorCore/Filters/Processors/Binarization/ThresholdProcessor.cs index e6f3e8b56b..dc3816a039 100644 --- a/src/ImageProcessorCore/Filters/Binarization/Threshold.cs +++ b/src/ImageProcessorCore/Filters/Processors/Binarization/ThresholdProcessor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; using System.Threading.Tasks; @@ -13,16 +13,16 @@ namespace ImageProcessorCore.Filters /// . The image will be converted to greyscale before thresholding /// occurs. /// - public class Threshold : ParallelImageProcessor + public class ThresholdProcessor : ParallelImageProcessor { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The threshold to split the image. Must be between 0 and 1. /// /// is less than 0 or is greater than 1. /// - public Threshold(float threshold) + public ThresholdProcessor(float threshold) { Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); this.Value = threshold; @@ -46,7 +46,7 @@ namespace ImageProcessorCore.Filters /// protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) { - new GreyscaleBt709().Apply(source, source, sourceRectangle); + new GreyscaleBt709Processor().Apply(source, source, sourceRectangle); } /// diff --git a/src/ImageProcessorCore/Filters/Processors/BlendProcessor.cs b/src/ImageProcessorCore/Filters/Processors/BlendProcessor.cs new file mode 100644 index 0000000000..cbf966a7c9 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/BlendProcessor.cs @@ -0,0 +1,86 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System.Threading.Tasks; + + /// + /// Combines two images together by blending the pixels. + /// + public class BlendProcessor : ParallelImageProcessor + { + /// + /// The image to blend. + /// + private readonly ImageBase blend; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The image to blend with the currently processing image. + /// Disposal of this image is the responsibility of the developer. + /// + /// The opacity of the image to blend. Between 0 and 100. + public BlendProcessor(ImageBase image, int alpha = 100) + { + Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha)); + this.blend = image; + this.Value = alpha; + } + + /// + /// Gets the alpha percentage value. + /// + public int Value { get; } + + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + Rectangle bounds = this.blend.Bounds; + float alpha = this.Value / 100f; + + using (PixelAccessor toBlendPixels = this.blend.Lock()) + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + startY, + endY, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x++) + { + Color color = sourcePixels[x, y]; + + if (bounds.Contains(x, y)) + { + Color blendedColor = toBlendPixels[x, y]; + + if (blendedColor.A > 0) + { + // Lerping colors is dependent on the alpha of the blended color + float alphaFactor = alpha > 0 ? alpha : blendedColor.A; + color = Color.Lerp(color, blendedColor, alphaFactor); + } + } + + targetPixels[x, y] = color; + } + + this.OnRowProcessed(); + } + }); + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs b/src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs new file mode 100644 index 0000000000..a100e5717f --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs @@ -0,0 +1,69 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System; + using System.Numerics; + using System.Threading.Tasks; + + /// + /// An to change the brightness of an . + /// + public class BrightnessProcessor : ParallelImageProcessor + { + /// + /// Initializes a new instance of the class. + /// + /// The new brightness of the image. Must be between -100 and 100. + /// + /// is less than -100 or is greater than 100. + /// + public BrightnessProcessor(int brightness) + { + Guard.MustBeBetweenOrEqualTo(brightness, -100, 100, nameof(brightness)); + this.Value = brightness; + } + + /// + /// Gets the brightness value. + /// + public int Value { get; } + + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + float brightness = this.Value / 100f; + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + startY, + endY, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x++) + { + Color color = Color.Expand(sourcePixels[x, y]); + + Vector3 vector3 = color.ToVector3(); + vector3 += new Vector3(brightness); + + targetPixels[x, y] = Color.Compress(new Color(vector3, color.A)); + } + this.OnRowProcessed(); + } + }); + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/BlackWhite.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs similarity index 79% rename from src/ImageProcessorCore/Filters/ColorMatrix/BlackWhite.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs index f0d2a366a9..7fc3240d00 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/BlackWhite.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image to their black and white equivalent. /// - public class BlackWhite : ColorMatrixFilter + public class BlackWhiteProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Achromatomaly.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs similarity index 79% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Achromatomaly.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs index b649fcba5d..d5740ec284 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Achromatomaly.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness. /// - public class Achromatomaly : ColorMatrixFilter + public class AchromatomalyProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Achromatopsia.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs similarity index 79% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Achromatopsia.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs index 794e71ca3c..6f2f7c2693 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Achromatopsia.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness. /// - public class Achromatopsia : ColorMatrixFilter + public class AchromatopsiaProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Deuteranomaly.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs similarity index 77% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Deuteranomaly.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs index a8f7d5f2ca..fed09991f6 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Deuteranomaly.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness. /// - public class Deuteranomaly : ColorMatrixFilter + public class DeuteranomalyProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Deuteranopia.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs similarity index 77% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Deuteranopia.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs index 630c2fa3cb..0ef190861b 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Deuteranopia.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness. /// - public class Deuteranopia : ColorMatrixFilter + public class DeuteranopiaProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Protanomaly.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs similarity index 78% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Protanomaly.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs index 73d3bdcaa5..b7152a68e4 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Protanomaly.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness. /// - public class Protanomaly : ColorMatrixFilter + public class ProtanomalyProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Protanopia.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs similarity index 78% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Protanopia.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs index a6cfef24e4..7984be139b 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Protanopia.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness. /// - public class Protanopia : ColorMatrixFilter + public class ProtanopiaProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/README.md b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/README.md similarity index 100% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/README.md rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/README.md diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Tritanomaly.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs similarity index 78% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Tritanomaly.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs index 851b179154..618da36bb9 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Tritanomaly.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness. /// - public class Tritanomaly : ColorMatrixFilter + public class TritanomalyProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Tritanopia.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs similarity index 78% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Tritanopia.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs index 338f0877c0..e53de7a69a 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorBlindness/Tritanopia.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness. /// - public class Tritanopia : ColorMatrixFilter + public class TritanopiaProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/ColorMatrixFilter.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs similarity index 98% rename from src/ImageProcessorCore/Filters/ColorMatrix/ColorMatrixFilter.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs index 8397a07cc1..eb01c3c226 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/ColorMatrixFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleBt601.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleBt601Processor.cs similarity index 80% rename from src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleBt601.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleBt601Processor.cs index 49ee2642e9..b9a6daa6e7 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleBt601.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleBt601Processor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; @@ -11,7 +11,7 @@ namespace ImageProcessorCore.Filters /// Converts the colors of the image to greyscale applying the formula as specified by /// ITU-R Recommendation BT.601 . /// - public class GreyscaleBt601 : ColorMatrixFilter + public class GreyscaleBt601Processor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleBt709.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleBt709Processor.cs similarity index 80% rename from src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleBt709.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleBt709Processor.cs index da0533d746..949e51e6a9 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleBt709.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleBt709Processor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; @@ -11,7 +11,7 @@ namespace ImageProcessorCore.Filters /// Converts the colors of the image to greyscale applying the formula as specified by /// ITU-R Recommendation BT.709 . /// - public class GreyscaleBt709 : ColorMatrixFilter + public class GreyscaleBt709Processor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleMode.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleMode.cs similarity index 93% rename from src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleMode.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleMode.cs index 27ddad9513..269c1179ef 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/GreyscaleMode.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/GreyscaleMode.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// Provides enumeration over the various greyscale methods available. diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/Hue.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/HueProcessor.cs similarity index 86% rename from src/ImageProcessorCore/Filters/ColorMatrix/Hue.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/HueProcessor.cs index 8d79a204aa..da7d4631c5 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/Hue.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/HueProcessor.cs @@ -1,9 +1,14 @@ -namespace ImageProcessorCore.Filters +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors { using System; using System.Numerics; - public class Hue : ColorMatrixFilter + public class HueProcessor : ColorMatrixFilter { /// /// The used to alter the image. @@ -11,10 +16,10 @@ private Matrix4x4 matrix; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The new brightness of the image. Must be between -100 and 100. - public Hue(float angle) + public HueProcessor(float angle) { // Wrap the angle round at 360. angle = angle % 360; diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/IColorMatrixFilter.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs similarity index 80% rename from src/ImageProcessorCore/Filters/ColorMatrix/IColorMatrixFilter.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs index 0845b521b9..5a0c766848 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/IColorMatrixFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; @@ -19,7 +19,8 @@ namespace ImageProcessorCore.Filters Matrix4x4 Matrix { get; } /// - /// Gets a value indicating whether to compand the value on processing. + /// Gets a value indicating whether to compress + /// or expand individual pixel colors the value on processing. /// bool Compand { get; } } diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/Kodachrome.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/KodachromeProcessor.cs similarity index 76% rename from src/ImageProcessorCore/Filters/ColorMatrix/Kodachrome.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/KodachromeProcessor.cs index 03f248fd9b..91c436460e 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/Kodachrome.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/KodachromeProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating an old Kodachrome camera effect. /// - public class Kodachrome : ColorMatrixFilter + public class KodachromeProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/Lomograph.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs similarity index 71% rename from src/ImageProcessorCore/Filters/ColorMatrix/Lomograph.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs index 9567a80567..4b507fcd13 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/Lomograph.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating an old Lomograph effect. /// - public class Lomograph : ColorMatrixFilter + public class LomographProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() @@ -26,7 +26,7 @@ namespace ImageProcessorCore.Filters /// protected override void AfterApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle) { - new Vignette { Color = new Color(0, 10 / 255f, 0) }.Apply(target, target, targetRectangle); + new VignetteProcessor { Color = new Color(0, 10 / 255f, 0) }.Apply(target, target, targetRectangle); } } } diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/Polaroid.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs similarity index 77% rename from src/ImageProcessorCore/Filters/ColorMatrix/Polaroid.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs index dfd877ca22..dce2609e5f 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/Polaroid.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; /// /// Converts the colors of the image recreating an old Polaroid effect. /// - public class Polaroid : ColorMatrixFilter + public class PolaroidProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() @@ -32,8 +32,8 @@ namespace ImageProcessorCore.Filters /// protected override void AfterApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle) { - new Vignette { Color = new Color(102 / 255f, 34 / 255f, 0) }.Apply(target, target, targetRectangle); - new Glow + new VignetteProcessor { Color = new Color(102 / 255f, 34 / 255f, 0) }.Apply(target, target, targetRectangle); + new GlowProcessor { Color = new Color(1, 153 / 255f, 102 / 255f, .7f), RadiusX = target.Width / 4f, diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/Saturation.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/SaturationProcessor.cs similarity index 91% rename from src/ImageProcessorCore/Filters/ColorMatrix/Saturation.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/SaturationProcessor.cs index 113afcb0c2..abc00bfb61 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/Saturation.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/SaturationProcessor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; using System.Numerics; @@ -11,7 +11,7 @@ namespace ImageProcessorCore.Filters /// /// An to change the saturation of an . /// - public class Saturation : ColorMatrixFilter + public class SaturationProcessor : ColorMatrixFilter { /// /// The saturation to be applied to the image. @@ -24,13 +24,13 @@ namespace ImageProcessorCore.Filters private Matrix4x4 matrix; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The new saturation of the image. Must be between -100 and 100. /// /// is less than -100 or is greater than 100. /// - public Saturation(int saturation) + public SaturationProcessor(int saturation) { Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation)); this.saturation = saturation; diff --git a/src/ImageProcessorCore/Filters/ColorMatrix/Sepia.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/SepiaProcessor.cs similarity index 82% rename from src/ImageProcessorCore/Filters/ColorMatrix/Sepia.cs rename to src/ImageProcessorCore/Filters/Processors/ColorMatrix/SepiaProcessor.cs index 2898e7b0ca..da68013110 100644 --- a/src/ImageProcessorCore/Filters/ColorMatrix/Sepia.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/SepiaProcessor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Numerics; @@ -11,7 +11,7 @@ namespace ImageProcessorCore.Filters /// Converts the colors of the image to their sepia equivalent. /// The formula used matches the svg specification. /// - public class Sepia : ColorMatrixFilter + public class SepiaProcessor : ColorMatrixFilter { /// public override Matrix4x4 Matrix => new Matrix4x4() diff --git a/src/ImageProcessorCore/Filters/Processors/ContrastProcessor.cs b/src/ImageProcessorCore/Filters/Processors/ContrastProcessor.cs new file mode 100644 index 0000000000..920a6fb01c --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/ContrastProcessor.cs @@ -0,0 +1,70 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System; + using System.Numerics; + using System.Threading.Tasks; + + /// + /// An to change the contrast of an . + /// + public class ContrastProcessor : ParallelImageProcessor + { + /// + /// Initializes a new instance of the class. + /// + /// The new contrast of the image. Must be between -100 and 100. + /// + /// is less than -100 or is greater than 100. + /// + public ContrastProcessor(int contrast) + { + Guard.MustBeBetweenOrEqualTo(contrast, -100, 100, nameof(contrast)); + this.Value = contrast; + } + + /// + /// Gets the contrast value. + /// + public int Value { get; } + + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + float contrast = (100f + this.Value) / 100f; + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1); + Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1); + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + startY, + endY, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x++) + { + Vector4 color = Color.Expand(sourcePixels[x, y]).ToVector4(); + color -= shiftVector; + color *= contrastVector; + color += shiftVector; + targetPixels[x, y] = Color.Compress(new Color(color)); + } + this.OnRowProcessed(); + } + }); + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Convolution/BoxBlur.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/BoxBlurProcessor.cs similarity index 92% rename from src/ImageProcessorCore/Filters/Convolution/BoxBlur.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/BoxBlurProcessor.cs index 5da2d2be67..4ad60d65b1 100644 --- a/src/ImageProcessorCore/Filters/Convolution/BoxBlur.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/BoxBlurProcessor.cs @@ -1,14 +1,14 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// Applies a Box blur filter to the image. /// - public class BoxBlur : Convolution2PassFilter + public class BoxBlurProcessor : Convolution2PassFilter { /// /// The maximum size of the kernal in either direction. @@ -26,12 +26,12 @@ namespace ImageProcessorCore.Filters private float[,] kernelX; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'radius' value representing the size of the area to sample. /// - public BoxBlur(int radius = 7) + public BoxBlurProcessor(int radius = 7) { this.kernelSize = (radius * 2) + 1; } diff --git a/src/ImageProcessorCore/Filters/Convolution/Convolution2DFilter.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2DFilter.cs similarity index 99% rename from src/ImageProcessorCore/Filters/Convolution/Convolution2DFilter.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2DFilter.cs index 2fd53f04c8..0dad68485c 100644 --- a/src/ImageProcessorCore/Filters/Convolution/Convolution2DFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2DFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Filters/Convolution/Convolution2PassFilter.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2PassFilter.cs similarity index 99% rename from src/ImageProcessorCore/Filters/Convolution/Convolution2PassFilter.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2PassFilter.cs index 7d9bda6c06..66e8cac982 100644 --- a/src/ImageProcessorCore/Filters/Convolution/Convolution2PassFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2PassFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Filters/Convolution/ConvolutionFilter.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/ConvolutionFilter.cs similarity index 98% rename from src/ImageProcessorCore/Filters/Convolution/ConvolutionFilter.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/ConvolutionFilter.cs index 5a5ee89d84..84884ff837 100644 --- a/src/ImageProcessorCore/Filters/Convolution/ConvolutionFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/ConvolutionFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/EdgeDetector2DFilter.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs similarity index 85% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/EdgeDetector2DFilter.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs index c37e6f23c9..ce4aa0b2aa 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/EdgeDetector2DFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// Defines a filter that detects edges within an image using two @@ -19,7 +19,7 @@ namespace ImageProcessorCore.Filters { if (this.Greyscale) { - new GreyscaleBt709().Apply(source, source, sourceRectangle); + new GreyscaleBt709Processor().Apply(source, source, sourceRectangle); } } } diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/EdgeDetectorFilter.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs similarity index 85% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/EdgeDetectorFilter.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs index 3795bb78c8..7a18bb96b3 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/EdgeDetectorFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// Defines a filter that detects edges within an image using a single @@ -19,7 +19,7 @@ namespace ImageProcessorCore.Filters { if (this.Greyscale) { - new GreyscaleBt709().Apply(source, source, sourceRectangle); + new GreyscaleBt709Processor().Apply(source, source, sourceRectangle); } } } diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/IEdgeDetectorFilter.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs similarity index 93% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/IEdgeDetectorFilter.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs index 0016dad662..b90f0d2ea2 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/IEdgeDetectorFilter.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// Provides properties and methods allowing the detection of edges within an image. diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Kayyali.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs similarity index 78% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Kayyali.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs index 2a8a193cd9..5af8182412 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Kayyali.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Kayyali operator filter. /// /// - public class Kayyali : EdgeDetector2DFilter + public class KayyaliProcessor : EdgeDetector2DFilter { /// public override float[,] KernelX => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Kirsch.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs similarity index 79% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Kirsch.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs index 88904494e7..24a561572e 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Kirsch.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Kirsch operator filter. /// /// - public class Kirsch : EdgeDetector2DFilter + public class KirschProcessor : EdgeDetector2DFilter { /// public override float[,] KernelX => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Laplacian3X3.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs similarity index 72% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Laplacian3X3.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs index d4d1824aa8..a66d692537 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Laplacian3X3.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Laplacian 3 x 3 operator filter. /// /// - public class Laplacian3X3 : EdgeDetectorFilter + public class Laplacian3X3Processor : EdgeDetectorFilter { /// public override float[,] KernelXY => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Laplacian5X5.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs similarity index 76% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Laplacian5X5.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs index 1456206b0e..f2d3d885ee 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Laplacian5X5.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Laplacian 5 x 5 operator filter. /// /// - public class Laplacian5X5 : EdgeDetectorFilter + public class Laplacian5X5Processor : EdgeDetectorFilter { /// public override float[,] KernelXY => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/LaplacianOfGaussian.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs similarity index 75% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/LaplacianOfGaussian.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs index 3a7e4c2e34..0aae3020a9 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/LaplacianOfGaussian.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Laplacian of Gaussian operator filter. /// /// - public class LaplacianOfGaussian : EdgeDetectorFilter + public class LaplacianOfGaussianProcessor : EdgeDetectorFilter { /// public override float[,] KernelXY => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Prewitt.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs similarity index 78% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Prewitt.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs index 0f0a99cc50..3a5bbe9860 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Prewitt.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Prewitt operator filter. /// /// - public class Prewitt : EdgeDetector2DFilter + public class PrewittProcessor : EdgeDetector2DFilter { /// public override float[,] KernelX => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/RobertsCross.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs similarity index 76% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/RobertsCross.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs index 6b80690916..0a61664184 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/RobertsCross.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Roberts Cross operator filter. /// /// - public class RobertsCross : EdgeDetector2DFilter + public class RobertsCrossProcessor : EdgeDetector2DFilter { /// public override float[,] KernelX => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Scharr.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs similarity index 79% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Scharr.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs index bca9587fce..80308a1409 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Scharr.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Scharr operator filter. /// /// - public class Scharr : EdgeDetector2DFilter + public class ScharrProcessor : EdgeDetector2DFilter { /// public override float[,] KernelX => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Sobel.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs similarity index 79% rename from src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Sobel.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs index 4cf0b71493..39f7d350d2 100644 --- a/src/ImageProcessorCore/Filters/Convolution/EdgeDetection/Sobel.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs @@ -1,15 +1,15 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { /// /// The Sobel operator filter. /// /// - public class Sobel : EdgeDetector2DFilter + public class SobelProcessor : EdgeDetector2DFilter { /// public override float[,] KernelX => new float[,] diff --git a/src/ImageProcessorCore/Filters/Convolution/GuassianBlur.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/GuassianBlurProcessor.cs similarity index 90% rename from src/ImageProcessorCore/Filters/Convolution/GuassianBlur.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/GuassianBlurProcessor.cs index ed4cb6d4fb..904de5994c 100644 --- a/src/ImageProcessorCore/Filters/Convolution/GuassianBlur.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/GuassianBlurProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; /// /// Applies a Gaussian blur filter to the image. /// - public class GuassianBlur : Convolution2PassFilter + public class GuassianBlurProcessor : Convolution2PassFilter { /// /// The maximum size of the kernal in either direction. @@ -33,29 +33,29 @@ namespace ImageProcessorCore.Filters private float[,] kernelX; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The 'sigma' value representing the weight of the blur. - public GuassianBlur(float sigma = 3f) + public GuassianBlurProcessor(float sigma = 3f) { this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; this.sigma = sigma; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'radius' value representing the size of the area to sample. /// - public GuassianBlur(int radius) + public GuassianBlurProcessor(int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = radius; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'sigma' value representing the weight of the blur. @@ -64,7 +64,7 @@ namespace ImageProcessorCore.Filters /// The 'radius' value representing the size of the area to sample. /// This should be at least twice the sigma value. /// - public GuassianBlur(float sigma, int radius) + public GuassianBlurProcessor(float sigma, int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = sigma; diff --git a/src/ImageProcessorCore/Filters/Convolution/GuassianSharpen.cs b/src/ImageProcessorCore/Filters/Processors/Convolution/GuassianSharpenProcessor.cs similarity index 92% rename from src/ImageProcessorCore/Filters/Convolution/GuassianSharpen.cs rename to src/ImageProcessorCore/Filters/Processors/Convolution/GuassianSharpenProcessor.cs index 7e64383cfe..8d95eaf829 100644 --- a/src/ImageProcessorCore/Filters/Convolution/GuassianSharpen.cs +++ b/src/ImageProcessorCore/Filters/Processors/Convolution/GuassianSharpenProcessor.cs @@ -1,16 +1,16 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; /// /// Applies a Gaussian sharpening filter to the image. /// - public class GuassianSharpen : Convolution2PassFilter + public class GuassianSharpenProcessor : Convolution2PassFilter { /// /// The maximum size of the kernal in either direction. @@ -33,31 +33,31 @@ namespace ImageProcessorCore.Filters private float[,] kernelX; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'sigma' value representing the weight of the sharpening. /// - public GuassianSharpen(float sigma = 3f) + public GuassianSharpenProcessor(float sigma = 3f) { this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; this.sigma = sigma; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'radius' value representing the size of the area to sample. /// - public GuassianSharpen(int radius) + public GuassianSharpenProcessor(int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = radius; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'sigma' value representing the weight of the sharpen. @@ -66,7 +66,7 @@ namespace ImageProcessorCore.Filters /// The 'radius' value representing the size of the area to sample. /// This should be at least twice the sigma value. /// - public GuassianSharpen(float sigma, int radius) + public GuassianSharpenProcessor(float sigma, int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = sigma; diff --git a/src/ImageProcessorCore/Filters/Glow.cs b/src/ImageProcessorCore/Filters/Processors/GlowProcessor.cs similarity index 92% rename from src/ImageProcessorCore/Filters/Glow.cs rename to src/ImageProcessorCore/Filters/Processors/GlowProcessor.cs index 3cca427e8e..63c18e9eb3 100644 --- a/src/ImageProcessorCore/Filters/Glow.cs +++ b/src/ImageProcessorCore/Filters/Processors/GlowProcessor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; using System.Numerics; @@ -12,7 +12,7 @@ namespace ImageProcessorCore.Filters /// /// Creates a glow effect on the image /// - public class Glow : ParallelImageProcessor + public class GlowProcessor : ParallelImageProcessor { /// /// Gets or sets the glow color to apply. diff --git a/src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs b/src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs new file mode 100644 index 0000000000..31ef3ceb81 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs @@ -0,0 +1,48 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System.Numerics; + using System.Threading.Tasks; + + /// + /// An to invert the colors of an . + /// + public class InvertProcessor : ParallelImageProcessor + { + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + Vector3 inverseVector = Vector3.One; + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + startY, + endY, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x++) + { + Color color = sourcePixels[x, y]; + Vector3 vector = inverseVector - color.ToVector3(); + targetPixels[x, y] = new Color(vector, color.A); + } + + this.OnRowProcessed(); + } + }); + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Processors/PixelateProcessor.cs b/src/ImageProcessorCore/Filters/Processors/PixelateProcessor.cs new file mode 100644 index 0000000000..6c129bbee3 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Processors/PixelateProcessor.cs @@ -0,0 +1,97 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageProcessorCore.Processors +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + /// + /// An to invert the colors of an . + /// + public class PixelateProcessor : ParallelImageProcessor + { + /// + /// Initializes a new instance of the class. + /// + /// The size of the pixels. Must be greater than 0. + /// + /// is less than 0 or equal to 0. + /// + public PixelateProcessor(int size) + { + Guard.MustBeGreaterThan(size, 0, nameof(size)); + this.Value = size; + } + + /// + public override int Parallelism { get; set; } = 1; + + /// + /// Gets or the pixel size. + /// + public int Value { get; } + + /// + protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + int sourceY = sourceRectangle.Y; + int sourceBottom = sourceRectangle.Bottom; + int startX = sourceRectangle.X; + int endX = sourceRectangle.Right; + int size = this.Value; + int offset = this.Value / 2; + + // Get the range on the y-plane to choose from. + IEnumerable range = EnumerableExtensions.SteppedRange(startY, i => i < endY, size); + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.ForEach( + range, + y => + { + if (y >= sourceY && y < sourceBottom) + { + for (int x = startX; x < endX; x += size) + { + + int offsetX = offset; + int offsetY = offset; + + // Make sure that the offset is within the boundary of the + // image. + while (y + offsetY >= sourceBottom) + { + offsetY--; + } + + while (x + offsetX >= endX) + { + offsetX--; + } + + // Get the pixel color in the centre of the soon to be pixelated area. + // ReSharper disable AccessToDisposedClosure + Color pixel = sourcePixels[x + offsetX, y + offsetY]; + + // For each pixel in the pixelate size, set it to the centre color. + for (int l = y; l < y + size && l < sourceBottom; l++) + { + for (int k = x; k < x + size && k < endX; k++) + { + targetPixels[k, l] = pixel; + } + } + } + this.OnRowProcessed(); + } + }); + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Vignette.cs b/src/ImageProcessorCore/Filters/Processors/VignetteProcessor.cs similarity index 92% rename from src/ImageProcessorCore/Filters/Vignette.cs rename to src/ImageProcessorCore/Filters/Processors/VignetteProcessor.cs index dcc2a18147..6a1bbc684e 100644 --- a/src/ImageProcessorCore/Filters/Vignette.cs +++ b/src/ImageProcessorCore/Filters/Processors/VignetteProcessor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore.Filters +namespace ImageProcessorCore.Processors { using System; using System.Numerics; @@ -12,7 +12,7 @@ namespace ImageProcessorCore.Filters /// /// Creates a vignette effect on the image /// - public class Vignette : ParallelImageProcessor + public class VignetteProcessor : ParallelImageProcessor { /// /// Gets or sets the vignette color to apply. diff --git a/src/ImageProcessorCore/Filters/Saturation.cs b/src/ImageProcessorCore/Filters/Saturation.cs new file mode 100644 index 0000000000..93c69fe3e7 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Saturation.cs @@ -0,0 +1,52 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Alters the saturation component of the image. + /// + /// The image this method extends. + /// The new saturation of the image. Must be between -100 and 100. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Saturation(this Image source, int amount, ProgressEventHandler progressHandler = null) + { + return Saturation(source, amount, source.Bounds, progressHandler); + } + + /// + /// Alters the saturation component of the image. + /// + /// The image this method extends. + /// The new saturation of the image. Must be between -100 and 100. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Saturation(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + SaturationProcessor processor = new SaturationProcessor(amount); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/Filters/Sepia.cs b/src/ImageProcessorCore/Filters/Sepia.cs new file mode 100644 index 0000000000..27d19b3194 --- /dev/null +++ b/src/ImageProcessorCore/Filters/Sepia.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// ------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessorCore +{ + using Processors; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Applies sepia toning to the image. + /// + /// The image this method extends. + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Sepia(this Image source, ProgressEventHandler progressHandler = null) + { + return Sepia(source, source.Bounds, progressHandler); + } + + /// + /// Applies sepia toning to the image. + /// + /// The image this method extends. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// A delegate which is called as progress is made processing the image. + /// The . + public static Image Sepia(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) + { + SepiaProcessor processor = new SepiaProcessor(); + processor.OnProgress += progressHandler; + + try + { + return source.Process(rectangle, processor); + } + finally + { + processor.OnProgress -= progressHandler; + } + } + } +} diff --git a/src/ImageProcessorCore/IImageProcessor.cs b/src/ImageProcessorCore/IImageProcessor.cs index 6eb649e84e..e71762b107 100644 --- a/src/ImageProcessorCore/IImageProcessor.cs +++ b/src/ImageProcessorCore/IImageProcessor.cs @@ -1,9 +1,9 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { /// /// A delegate which is called as progress is made processing an image. diff --git a/src/ImageProcessorCore/ImageExtensions.cs b/src/ImageProcessorCore/ImageExtensions.cs index cd5bea6242..e7b261d608 100644 --- a/src/ImageProcessorCore/ImageExtensions.cs +++ b/src/ImageProcessorCore/ImageExtensions.cs @@ -9,6 +9,7 @@ namespace ImageProcessorCore using System.IO; using Formats; + using Processors; /// /// Extension methods for the type. diff --git a/src/ImageProcessorCore/ParallelImageProcessor.cs b/src/ImageProcessorCore/ParallelImageProcessor.cs index fd47b2357f..a6b9fc3547 100644 --- a/src/ImageProcessorCore/ParallelImageProcessor.cs +++ b/src/ImageProcessorCore/ParallelImageProcessor.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { using System; using System.Threading; diff --git a/src/ImageProcessorCore/PixelAccessor.cs b/src/ImageProcessorCore/PixelAccessor.cs index 3f7ac433dc..8f1f4e2312 100644 --- a/src/ImageProcessorCore/PixelAccessor.cs +++ b/src/ImageProcessorCore/PixelAccessor.cs @@ -53,7 +53,7 @@ namespace ImageProcessorCore this.Height = image.Height; // Assign the pointer. - // If buffer is allocated on Large Object Heap, then we are going to pin it instead of making a copy. + // If buffer is allocated on Large Object Heap i.e > 85Kb, then we are going to pin it instead of making a copy. if (size > (85 * 1024)) { this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned); diff --git a/src/ImageProcessorCore/Samplers/Crop.cs b/src/ImageProcessorCore/Samplers/Crop.cs index 23f4d18f58..239fd63f14 100644 --- a/src/ImageProcessorCore/Samplers/Crop.cs +++ b/src/ImageProcessorCore/Samplers/Crop.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/src/ImageProcessorCore/Samplers/EntropyCrop.cs b/src/ImageProcessorCore/Samplers/EntropyCrop.cs index 8a6cafc758..55284668ca 100644 --- a/src/ImageProcessorCore/Samplers/EntropyCrop.cs +++ b/src/ImageProcessorCore/Samplers/EntropyCrop.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/src/ImageProcessorCore/Samplers/Pad.cs b/src/ImageProcessorCore/Samplers/Pad.cs index fcdac92008..de973d3454 100644 --- a/src/ImageProcessorCore/Samplers/Pad.cs +++ b/src/ImageProcessorCore/Samplers/Pad.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/src/ImageProcessorCore/Samplers/Processors/CropProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/CropProcessor.cs index c25cfe08d7..e6707afa09 100644 --- a/src/ImageProcessorCore/Samplers/Processors/CropProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/CropProcessor.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs index 0d4632472d..e0ffb29e10 100644 --- a/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs @@ -3,13 +3,11 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { using System; using System.Threading.Tasks; - using Filters; - /// /// Provides methods to allow the cropping of an image to preserve areas of highest /// entropy. @@ -45,10 +43,10 @@ namespace ImageProcessorCore ImageBase temp = new Image(source.Width, source.Height); // Detect the edges. - new Sobel().Apply(temp, source, sourceRectangle); + new SobelProcessor().Apply(temp, source, sourceRectangle); // Apply threshold binarization filter. - new Threshold(.5f).Apply(temp, temp, sourceRectangle); + new ThresholdProcessor(.5f).Apply(temp, temp, sourceRectangle); // Search for the first white pixels Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); diff --git a/src/ImageProcessorCore/Samplers/Processors/IImageSampler.cs b/src/ImageProcessorCore/Samplers/Processors/IImageSampler.cs index 69e017c527..76a2c5a4d4 100644 --- a/src/ImageProcessorCore/Samplers/Processors/IImageSampler.cs +++ b/src/ImageProcessorCore/Samplers/Processors/IImageSampler.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { /// /// Acts as a marker for generic parameters that require an image sampler. diff --git a/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs b/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs index ee1a7dd7e9..cc8bfe4cc3 100644 --- a/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs +++ b/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { /// /// Applies sampling methods to an image. diff --git a/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs index 0cc75822b1..82b07d40b5 100644 --- a/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { using System; using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Samplers/Processors/RotateFlip.cs b/src/ImageProcessorCore/Samplers/Processors/RotateFlipProcessor.cs similarity index 99% rename from src/ImageProcessorCore/Samplers/Processors/RotateFlip.cs rename to src/ImageProcessorCore/Samplers/Processors/RotateFlipProcessor.cs index 570ff9c4fc..263242fc10 100644 --- a/src/ImageProcessorCore/Samplers/Processors/RotateFlip.cs +++ b/src/ImageProcessorCore/Samplers/Processors/RotateFlipProcessor.cs @@ -2,7 +2,8 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore + +namespace ImageProcessorCore.Processors { using System; using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs index 8b264a8fa9..c4fbdfd148 100644 --- a/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { using System.Numerics; using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs index 2d0ce233e7..82a8d5cffa 100644 --- a/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs @@ -3,7 +3,7 @@ // Licensed under the Apache License, Version 2.0. // -namespace ImageProcessorCore +namespace ImageProcessorCore.Processors { using System.Numerics; using System.Threading.Tasks; diff --git a/src/ImageProcessorCore/Samplers/Resize.cs b/src/ImageProcessorCore/Samplers/Resize.cs index a90c4c105f..2eadd7a11c 100644 --- a/src/ImageProcessorCore/Samplers/Resize.cs +++ b/src/ImageProcessorCore/Samplers/Resize.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/src/ImageProcessorCore/Samplers/Rotate.cs b/src/ImageProcessorCore/Samplers/Rotate.cs index 49441fbb58..ea24f9650f 100644 --- a/src/ImageProcessorCore/Samplers/Rotate.cs +++ b/src/ImageProcessorCore/Samplers/Rotate.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/src/ImageProcessorCore/Samplers/RotateFlip.cs b/src/ImageProcessorCore/Samplers/RotateFlip.cs index 279bd274bf..93449bcd06 100644 --- a/src/ImageProcessorCore/Samplers/RotateFlip.cs +++ b/src/ImageProcessorCore/Samplers/RotateFlip.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/src/ImageProcessorCore/Samplers/Skew.cs b/src/ImageProcessorCore/Samplers/Skew.cs index 7e9088ab91..7b0587a524 100644 --- a/src/ImageProcessorCore/Samplers/Skew.cs +++ b/src/ImageProcessorCore/Samplers/Skew.cs @@ -5,6 +5,8 @@ namespace ImageProcessorCore { + using Processors; + /// /// Extension methods for the type. /// diff --git a/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs b/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs index 9c8d39ba8e..5632fe5a1b 100644 --- a/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs +++ b/tests/ImageProcessorCore.Tests/Processors/Filters/FilterTests.cs @@ -4,7 +4,7 @@ namespace ImageProcessorCore.Tests using System.Diagnostics; using System.IO; - using ImageProcessorCore.Filters; + using Processors; using Xunit; @@ -12,47 +12,47 @@ namespace ImageProcessorCore.Tests { public static readonly TheoryData Filters = new TheoryData { - { "Brightness-50", new Brightness(50) }, - { "Brightness--50", new Brightness(-50) }, - { "Contrast-50", new Contrast(50) }, - { "Contrast--50", new Contrast(-50) }, - { "BackgroundColor", new BackgroundColor(new Color(243 / 255f, 87 / 255f, 161 / 255f,.5f))}, - { "Blend", new Blend(new Image(File.OpenRead("TestImages/Formats/Bmp/Car.bmp")),50)}, - { "Saturation-50", new Saturation(50) }, - { "Saturation--50", new Saturation(-50) }, - { "Alpha--50", new Alpha(50) }, - { "Invert", new Invert() }, - { "Sepia", new Sepia() }, - { "BlackWhite", new BlackWhite() }, - { "Lomograph", new Lomograph() }, - { "Polaroid", new Polaroid() }, - { "Kodachrome", new Kodachrome() }, - { "GreyscaleBt709", new GreyscaleBt709() }, - { "GreyscaleBt601", new GreyscaleBt601() }, - { "Kayyali", new Kayyali() }, - { "Kirsch", new Kirsch() }, - { "Laplacian3X3", new Laplacian3X3() }, - { "Laplacian5X5", new Laplacian5X5() }, - { "LaplacianOfGaussian", new LaplacianOfGaussian() }, - { "Prewitt", new Prewitt() }, - { "RobertsCross", new RobertsCross() }, - { "Scharr", new Scharr() }, - { "Sobel", new Sobel {Greyscale = true} }, - { "Pixelate", new Pixelate(8) }, - { "GuassianBlur", new GuassianBlur(10) }, - { "GuassianSharpen", new GuassianSharpen(10) }, - { "Hue-180", new Hue(180) }, - { "Hue--180", new Hue(-180) }, - { "BoxBlur", new BoxBlur(10) }, - { "Vignette", new Vignette() }, - { "Protanopia", new Protanopia() }, - { "Protanomaly", new Protanomaly() }, - { "Deuteranopia", new Deuteranopia() }, - { "Deuteranomaly", new Deuteranomaly() }, - { "Tritanopia", new Tritanopia() }, - { "Tritanomaly", new Tritanomaly() }, - { "Achromatopsia", new Achromatopsia() }, - { "Achromatomaly", new Achromatomaly() } + { "Brightness-50", new BrightnessProcessor(50) }, + { "Brightness--50", new BrightnessProcessor(-50) }, + { "Contrast-50", new ContrastProcessor(50) }, + { "Contrast--50", new ContrastProcessor(-50) }, + { "BackgroundColor", new BackgroundColorProcessor(new Color(243 / 255f, 87 / 255f, 161 / 255f,.5f))}, + { "Blend", new BlendProcessor(new Image(File.OpenRead("TestImages/Formats/Bmp/Car.bmp")),50)}, + { "Saturation-50", new SaturationProcessor(50) }, + { "Saturation--50", new SaturationProcessor(-50) }, + { "Alpha--50", new AlphaProcessor(50) }, + { "Invert", new InvertProcessor() }, + { "Sepia", new SepiaProcessor() }, + { "BlackWhite", new BlackWhiteProcessor() }, + { "Lomograph", new LomographProcessor() }, + { "Polaroid", new PolaroidProcessor() }, + { "Kodachrome", new KodachromeProcessor() }, + { "GreyscaleBt709", new GreyscaleBt709Processor() }, + { "GreyscaleBt601", new GreyscaleBt601Processor() }, + { "Kayyali", new KayyaliProcessor() }, + { "Kirsch", new KirschProcessor() }, + { "Laplacian3X3", new Laplacian3X3Processor() }, + { "Laplacian5X5", new Laplacian5X5Processor() }, + { "LaplacianOfGaussian", new LaplacianOfGaussianProcessor() }, + { "Prewitt", new PrewittProcessor() }, + { "RobertsCross", new RobertsCrossProcessor() }, + { "Scharr", new ScharrProcessor() }, + { "Sobel", new SobelProcessor {Greyscale = true} }, + { "Pixelate", new PixelateProcessor(8) }, + { "GuassianBlur", new GuassianBlurProcessor(10) }, + { "GuassianSharpen", new GuassianSharpenProcessor(10) }, + { "Hue-180", new HueProcessor(180) }, + { "Hue--180", new HueProcessor(-180) }, + { "BoxBlur", new BoxBlurProcessor(10) }, + { "Vignette", new VignetteProcessor() }, + { "Protanopia", new ProtanopiaProcessor() }, + { "Protanomaly", new ProtanomalyProcessor() }, + { "Deuteranopia", new DeuteranopiaProcessor() }, + { "Deuteranomaly", new DeuteranomalyProcessor() }, + { "Tritanopia", new TritanopiaProcessor() }, + { "Tritanomaly", new TritanomalyProcessor() }, + { "Achromatopsia", new AchromatopsiaProcessor() }, + { "Achromatomaly", new AchromatomalyProcessor() } }; diff --git a/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs index 5009d596b9..d9a8608d1f 100644 --- a/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs +++ b/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs @@ -3,10 +3,9 @@ using System.Diagnostics; using System.IO; - using ImageProcessorCore.Processors; + using Processors; using Xunit; - using Filters; public class SamplerTests : FileTestBase {