From 4f7f51ae7a382fb55588ff99e6950ae3f0eaa8b8 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2016 17:34:54 +1100 Subject: [PATCH 01/15] Move Crop --- .../Common/Extensions/ArrayExtensions.cs | 29 +++++++ .../Common/Extensions/ByteExtensions.cs | 4 +- .../Processors/Transforms/CropProcessor.cs | 76 +++++++++++++++++++ .../{Samplers => Filters}/Transforms/Crop.cs | 6 +- src/ImageSharp/Image/PixelAccessor.cs | 26 +++++++ .../Processors/Transforms/CropProcessor.cs | 49 ------------ .../{Samplers => Filters}/CropTest.cs | 0 7 files changed, 135 insertions(+), 55 deletions(-) create mode 100644 src/ImageSharp/Common/Extensions/ArrayExtensions.cs create mode 100644 src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs rename src/ImageSharp/{Samplers => Filters}/Transforms/Crop.cs (95%) delete mode 100644 src/ImageSharp/Samplers/Processors/Transforms/CropProcessor.cs rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/CropTest.cs (100%) diff --git a/src/ImageSharp/Common/Extensions/ArrayExtensions.cs b/src/ImageSharp/Common/Extensions/ArrayExtensions.cs new file mode 100644 index 000000000..57ca37217 --- /dev/null +++ b/src/ImageSharp/Common/Extensions/ArrayExtensions.cs @@ -0,0 +1,29 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + /// + /// Extension methods for arrays. + /// + public static class ArrayExtensions + { + /// + /// Locks the pixel buffer providing access to the pixels. + /// + /// The pixel format. + /// The packed format. uint, long, float. + /// The pixel buffer. + /// Gets the width of the image represented by the pixel buffer. + /// The height of the image represented by the pixel buffer. + /// The + public static PixelAccessor Lock(this TColor[] pixels, int width, int height) + where TColor : struct, IPackedPixel + where TPacked : struct + { + return new PixelAccessor(width, height, pixels); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Extensions/ByteExtensions.cs b/src/ImageSharp/Common/Extensions/ByteExtensions.cs index 350777387..fc9c29e62 100644 --- a/src/ImageSharp/Common/Extensions/ByteExtensions.cs +++ b/src/ImageSharp/Common/Extensions/ByteExtensions.cs @@ -5,8 +5,6 @@ namespace ImageSharp { - using System; - /// /// Extension methods for the struct. /// @@ -44,4 +42,4 @@ namespace ImageSharp } } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs new file mode 100644 index 000000000..789538b2c --- /dev/null +++ b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs @@ -0,0 +1,76 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Processors +{ + using System.Threading.Tasks; + + /// + /// Provides methods to allow the cropping of an image. + /// + /// The pixel format. + /// The packed format. uint, long, float. + public class CropProcessor : ImageFilteringProcessor + where TColor : struct, IPackedPixel + where TPacked : struct + { + /// + /// Initializes a new instance of the class. + /// + /// The target image width. + /// The target image height. + public CropProcessor(int width, int height) + { + this.Width = width; + this.Height = height; + } + + /// + /// Gets the width. + /// + public int Width { get; } + + /// + /// Gets the height. + /// + public int Height { get; } + + /// + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + { + int minX = 0; + int maxX = this.Width; + int minY = 0; + int maxY = this.Height; + int sourceX = sourceRectangle.X; + int sourceY = sourceRectangle.Y; + + Guard.MustBeGreaterThanOrEqualTo(minX, sourceX, nameof(minX)); + Guard.MustBeGreaterThanOrEqualTo(minY, startY, nameof(startY)); + Guard.MustBeLessThanOrEqualTo(maxX, sourceRectangle.Right, nameof(maxX)); + Guard.MustBeLessThanOrEqualTo(maxY, endY, nameof(maxY)); + + TColor[] target = new TColor[this.Width * this.Height]; + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock(this.Width, this.Height)) + { + Parallel.For( + minY, + maxY, + this.ParallelOptions, + y => + { + for (int x = minX; x < maxX; x++) + { + targetPixels[x, y] = sourcePixels[x + sourceX, y + sourceY]; + } + }); + } + + source.SetPixels(this.Width, this.Height, target); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Transforms/Crop.cs b/src/ImageSharp/Filters/Transforms/Crop.cs similarity index 95% rename from src/ImageSharp/Samplers/Transforms/Crop.cs rename to src/ImageSharp/Filters/Transforms/Crop.cs index a266db3b2..95091358c 100644 --- a/src/ImageSharp/Samplers/Transforms/Crop.cs +++ b/src/ImageSharp/Filters/Transforms/Crop.cs @@ -58,8 +58,8 @@ namespace ImageSharp source = source.Resize(sourceRectangle.Width, sourceRectangle.Height); } - CropProcessor processor = new CropProcessor(); - return source.Process(width, height, sourceRectangle, new Rectangle(0, 0, width, height), processor); + CropProcessor processor = new CropProcessor(width, height); + return source.Process(sourceRectangle, processor); } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Image/PixelAccessor.cs b/src/ImageSharp/Image/PixelAccessor.cs index f11082df7..8f693584b 100644 --- a/src/ImageSharp/Image/PixelAccessor.cs +++ b/src/ImageSharp/Image/PixelAccessor.cs @@ -64,6 +64,32 @@ namespace ImageSharp this.RowStride = this.Width * this.PixelSize; } + /// + /// Initializes a new instance of the class. + /// + /// Gets the width of the image represented by the pixel buffer. + /// The height of the image represented by the pixel buffer. + /// The pixel buffer. + public PixelAccessor(int width, int height, TColor[] pixels) + { + Guard.NotNull(pixels, nameof(pixels)); + Guard.MustBeGreaterThan(width, 0, nameof(width)); + Guard.MustBeGreaterThan(height, 0, nameof(height)); + + if (pixels.Length != width * height) + { + throw new ArgumentException("Pixel array must have the length of Width * Height."); + } + + this.Width = width; + this.Height = height; + this.pixelsHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned); + this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); + this.pixelsBase = (byte*)this.dataPointer.ToPointer(); + this.PixelSize = Unsafe.SizeOf(); + this.RowStride = this.Width * this.PixelSize; + } + /// /// Finalizes an instance of the class. /// diff --git a/src/ImageSharp/Samplers/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Samplers/Processors/Transforms/CropProcessor.cs deleted file mode 100644 index 3a479fa2d..000000000 --- a/src/ImageSharp/Samplers/Processors/Transforms/CropProcessor.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Processors -{ - using System.Threading.Tasks; - - /// - /// Provides methods to allow the cropping of an image. - /// - /// The pixel format. - /// The packed format. uint, long, float. - public class CropProcessor : ImageSamplingProcessor - where TColor : struct, IPackedPixel - where TPacked : struct - { - /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - { - int startX = targetRectangle.X; - int endX = targetRectangle.Right; - int sourceX = sourceRectangle.X; - int sourceY = sourceRectangle.Y; - - Guard.MustBeGreaterThanOrEqualTo(startX, sourceX, nameof(targetRectangle)); - Guard.MustBeGreaterThanOrEqualTo(startY, sourceY, nameof(targetRectangle)); - Guard.MustBeLessThanOrEqualTo(endX, sourceRectangle.Right, nameof(targetRectangle)); - Guard.MustBeLessThanOrEqualTo(endY, sourceRectangle.Bottom, nameof(targetRectangle)); - - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) - { - Parallel.For( - startY, - endY, - this.ParallelOptions, - y => - { - for (int x = startX; x < endX; x++) - { - targetPixels[x, y] = sourcePixels[x + sourceX, y + sourceY]; - } - }); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Samplers/CropTest.cs b/tests/ImageSharp.Tests/Processors/Filters/CropTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/CropTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/CropTest.cs From c040582df6ba3abaf10269decd7ef3f9eeebb18a Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2016 22:56:49 +1100 Subject: [PATCH 02/15] Update Crop method to accept rectangle --- .../Processors/Transforms/CropProcessor.cs | 37 +++++++++---------- src/ImageSharp/Filters/Transforms/Crop.cs | 30 ++++----------- 2 files changed, 24 insertions(+), 43 deletions(-) diff --git a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs index 789538b2c..68c196113 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs @@ -5,6 +5,7 @@ namespace ImageSharp.Processors { + using System; using System.Threading.Tasks; /// @@ -19,18 +20,16 @@ namespace ImageSharp.Processors /// /// Initializes a new instance of the class. /// - /// The target image width. - /// The target image height. - public CropProcessor(int width, int height) + /// The target cropped rectangle. + public CropProcessor(Rectangle cropRectangle) { - this.Width = width; - this.Height = height; + this.CropRectangle = cropRectangle; } /// /// Gets the width. /// - public int Width { get; } + public Rectangle CropRectangle { get; } /// /// Gets the height. @@ -40,22 +39,20 @@ namespace ImageSharp.Processors /// protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - int minX = 0; - int maxX = this.Width; - int minY = 0; - int maxY = this.Height; - int sourceX = sourceRectangle.X; - int sourceY = sourceRectangle.Y; + if (this.CropRectangle == sourceRectangle) + { + return; + } - Guard.MustBeGreaterThanOrEqualTo(minX, sourceX, nameof(minX)); - Guard.MustBeGreaterThanOrEqualTo(minY, startY, nameof(startY)); - Guard.MustBeLessThanOrEqualTo(maxX, sourceRectangle.Right, nameof(maxX)); - Guard.MustBeLessThanOrEqualTo(maxY, endY, nameof(maxY)); + int minY = Math.Max(this.CropRectangle.Y, startY); + int maxY = Math.Min(this.CropRectangle.Bottom, endY); + int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X); + int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right); - TColor[] target = new TColor[this.Width * this.Height]; + TColor[] target = new TColor[this.CropRectangle.Width * this.CropRectangle.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock(this.Width, this.Height)) + using (PixelAccessor targetPixels = target.Lock(this.CropRectangle.Width, this.CropRectangle.Height)) { Parallel.For( minY, @@ -65,12 +62,12 @@ namespace ImageSharp.Processors { for (int x = minX; x < maxX; x++) { - targetPixels[x, y] = sourcePixels[x + sourceX, y + sourceY]; + targetPixels[x - minX, y - minY] = sourcePixels[x, y]; } }); } - source.SetPixels(this.Width, this.Height, target); + source.SetPixels(this.CropRectangle.Width, this.CropRectangle.Height, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Filters/Transforms/Crop.cs b/src/ImageSharp/Filters/Transforms/Crop.cs index 95091358c..d0c8ab8d8 100644 --- a/src/ImageSharp/Filters/Transforms/Crop.cs +++ b/src/ImageSharp/Filters/Transforms/Crop.cs @@ -25,41 +25,25 @@ namespace ImageSharp where TColor : struct, IPackedPixel where TPacked : struct { - return Crop(source, width, height, source.Bounds); + return Crop(source, new Rectangle(0, 0, width, height)); } /// - /// Crops an image to the given width and height with the given source rectangle. - /// - /// If the source rectangle is smaller than the target dimensions then the - /// area within the source is resized performing a zoomed crop. - /// + /// Crops an image to the given rectangle. /// /// The pixel format. /// The packed format. uint, long, float. /// The image to crop. - /// The target image width. - /// The target image height. - /// - /// The structure that specifies the portion of the image object to draw. + /// + /// The structure that specifies the portion of the image object to retain. /// /// The - public static Image Crop(this Image source, int width, int height, Rectangle sourceRectangle) + public static Image Crop(this Image source, Rectangle cropRectangle) where TColor : struct, IPackedPixel where TPacked : struct { - Guard.MustBeGreaterThan(width, 0, nameof(width)); - Guard.MustBeGreaterThan(height, 0, nameof(height)); - - if (sourceRectangle.Width < width || sourceRectangle.Height < height) - { - // If the source rectangle is smaller than the target perform a - // cropped zoom. - source = source.Resize(sourceRectangle.Width, sourceRectangle.Height); - } - - CropProcessor processor = new CropProcessor(width, height); - return source.Process(sourceRectangle, processor); + CropProcessor processor = new CropProcessor(cropRectangle); + return source.Process(source.Bounds, processor); } } } \ No newline at end of file From fc1aa565126b6ee04c328cda00d7614c70b42a93 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2016 22:57:07 +1100 Subject: [PATCH 03/15] Move Entropy Crop --- .../Transforms/EntropyCropProcessor.cs | 58 ++++++++++ .../Transforms/EntropyCrop.cs | 3 +- .../Transforms/EntropyCropProcessor.cs | 107 ------------------ 3 files changed, 60 insertions(+), 108 deletions(-) create mode 100644 src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs rename src/ImageSharp/{Samplers => Filters}/Transforms/EntropyCrop.cs (87%) delete mode 100644 src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs diff --git a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs new file mode 100644 index 000000000..6a5fd867a --- /dev/null +++ b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs @@ -0,0 +1,58 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Processors +{ + /// + /// Provides methods to allow the cropping of an image to preserve areas of highest + /// entropy. + /// + /// The pixel format. + /// The packed format. uint, long, float. + public class EntropyCropProcessor : ImageFilteringProcessor + where TColor : struct, IPackedPixel + where TPacked : struct + { + /// + /// 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 EntropyCropProcessor(float threshold) + { + Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); + this.Value = threshold; + } + + /// + /// Gets the threshold value. + /// + public float Value { get; } + + /// + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + { + ImageBase temp = new Image(source.Width, source.Height); + + // Detect the edges. + new SobelProcessor().Apply(temp, source, sourceRectangle); + + // Apply threshold binarization filter. + new BinaryThresholdProcessor(this.Value).Apply(temp, sourceRectangle); + + // Search for the first white pixels + Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); + + if (rectangle == sourceRectangle) + { + return; + } + + new CropProcessor(rectangle).Apply(source, sourceRectangle); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Transforms/EntropyCrop.cs b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs similarity index 87% rename from src/ImageSharp/Samplers/Transforms/EntropyCrop.cs rename to src/ImageSharp/Filters/Transforms/EntropyCrop.cs index 28a2ebf48..17fb109ee 100644 --- a/src/ImageSharp/Samplers/Transforms/EntropyCrop.cs +++ b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs @@ -25,7 +25,8 @@ namespace ImageSharp where TPacked : struct { EntropyCropProcessor processor = new EntropyCropProcessor(threshold); - return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor); + return source.Process(source.Bounds, processor); + // return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs deleted file mode 100644 index f9c8b2ae4..000000000 --- a/src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Processors -{ - using System; - using System.Threading.Tasks; - - /// - /// Provides methods to allow the cropping of an image to preserve areas of highest - /// entropy. - /// - /// The pixel format. - /// The packed format. uint, long, float. - public class EntropyCropProcessor : ImageSamplingProcessor - where TColor : struct, IPackedPixel - where TPacked : struct - { - /// - /// The rectangle for cropping - /// - private Rectangle cropRectangle; - - /// - /// 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 EntropyCropProcessor(float threshold) - { - Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); - this.Value = threshold; - } - - /// - /// Gets the threshold value. - /// - public float Value { get; } - - /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - { - // Jump out, we'll deal with that later. - if (source.Bounds == target.Bounds) - { - return; - } - - int targetY = this.cropRectangle.Y; - int targetBottom = this.cropRectangle.Bottom; - int startX = this.cropRectangle.X; - int endX = this.cropRectangle.Right; - - int minY = Math.Max(targetY, startY); - int maxY = Math.Min(targetBottom, endY); - - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) - { - Parallel.For( - minY, - maxY, - this.ParallelOptions, - y => - { - for (int x = startX; x < endX; x++) - { - targetPixels[x - startX, y - targetY] = sourcePixels[x, y]; - } - }); - } - } - - /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - ImageBase temp = new Image(source.Width, source.Height); - - // Detect the edges. - new SobelProcessor().Apply(temp, source, sourceRectangle); - - // Apply threshold binarization filter. - new BinaryThresholdProcessor(.5f).Apply(temp, sourceRectangle); - - // Search for the first white pixels - Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); - - // Reset the target pixel to the correct size. - target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]); - this.cropRectangle = rectangle; - } - - /// - protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - // Copy the pixels over. - if (source.Bounds == target.Bounds) - { - target.ClonePixels(target.Width, target.Height, source.Pixels); - } - } - } -} \ No newline at end of file From 769c6e6253ed4e1d6c0651133bebbde2092e3e17 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2016 23:06:03 +1100 Subject: [PATCH 04/15] Remove unused property --- .../Filters/Processors/Transforms/CropProcessor.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs index 68c196113..1e7916d06 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs @@ -31,11 +31,6 @@ namespace ImageSharp.Processors /// public Rectangle CropRectangle { get; } - /// - /// Gets the height. - /// - public int Height { get; } - /// protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { From d59e569ce8af8657b18430ed4ce1925aaabda01b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 01:56:29 +1100 Subject: [PATCH 05/15] Move Resize and fix tests. --- .../Transforms/CompandingResizeProcessor.cs | 77 +++++++++++-------- .../Transforms/EntropyCropProcessor.cs | 2 +- .../Transforms/ResamplingWeightedProcessor.cs | 47 +++++++---- .../Processors/Transforms/ResizeProcessor.cs | 77 +++++++++++-------- .../Filters/Transforms/EntropyCrop.cs | 2 +- .../Transforms/Resize.cs | 6 +- .../Processors/Samplers/ResizeTests.cs | 5 +- 7 files changed, 128 insertions(+), 88 deletions(-) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/CompandingResizeProcessor.cs (69%) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/ResamplingWeightedProcessor.cs (80%) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/ResizeProcessor.cs (69%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resize.cs (98%) diff --git a/src/ImageSharp/Samplers/Processors/Transforms/CompandingResizeProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs similarity index 69% rename from src/ImageSharp/Samplers/Processors/Transforms/CompandingResizeProcessor.cs rename to src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs index 1028622ef..3c6562dc0 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/CompandingResizeProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs @@ -22,11 +22,25 @@ namespace ImageSharp.Processors /// /// Initializes a new instance of the class. /// - /// - /// The sampler to perform the resize operation. + /// The sampler to perform the resize operation. + /// The target width. + /// The target height. + public CompandingResizeProcessor(IResampler sampler, int width, int height) + : base(sampler, width, height, new Rectangle(0, 0, width, height)) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The sampler to perform the resize operation. + /// The target width. + /// The target height. + /// + /// The structure that specifies the portion of the target image object to draw to. /// - public CompandingResizeProcessor(IResampler sampler) - : base(sampler) + public CompandingResizeProcessor(IResampler sampler, int width, int height, Rectangle resizeRectangle) + : base(sampler, width, height, resizeRectangle) { } @@ -34,37 +48,38 @@ namespace ImageSharp.Processors public override bool Compand { get; set; } = true; /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { // Jump out, we'll deal with that later. - if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle) + if (source.Width == this.Width && source.Height == this.Height && sourceRectangle == this.ResizeRectangle) { return; } - int width = target.Width; - int height = target.Height; - int sourceHeight = sourceRectangle.Height; - int targetX = target.Bounds.X; - int targetY = target.Bounds.Y; - int targetRight = target.Bounds.Right; - int targetBottom = target.Bounds.Bottom; - int startX = targetRectangle.X; - int endX = targetRectangle.Right; - - int minX = Math.Max(targetX, startX); - int maxX = Math.Min(targetRight, endX); - int minY = Math.Max(targetY, startY); - int maxY = Math.Min(targetBottom, endY); + // Reset the values as the rectangle can be altered by ResizeRectangle. + startY = this.ResizeRectangle.Y; + endY = this.ResizeRectangle.Bottom; + + int width = this.Width; + int height = this.Height; + int startX = this.ResizeRectangle.X; + int endX = this.ResizeRectangle.Right; + + int minX = Math.Max(0, startX); + int maxX = Math.Min(width, endX); + int minY = Math.Max(0, startY); + int maxY = Math.Min(height, endY); + + TColor[] target = new TColor[width * height]; if (this.Sampler is NearestNeighborResampler) { // Scaling factors - float widthFactor = sourceRectangle.Width / (float)targetRectangle.Width; - float heightFactor = sourceRectangle.Height / (float)targetRectangle.Height; + float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width; + float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( minY, @@ -84,6 +99,7 @@ namespace ImageSharp.Processors } // Break out now. + source.SetPixels(width, height, target); return; } @@ -91,19 +107,14 @@ namespace ImageSharp.Processors // A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm // First process the columns. Since we are not using multiple threads startY and endY // are the upper and lower bounds of the source rectangle. - Image firstPass = new Image(target.Width, source.Height); + TColor[] firstPass = new TColor[width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor firstPassPixels = firstPass.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor firstPassPixels = firstPass.Lock(width, source.Height)) + using (PixelAccessor targetPixels = target.Lock(width, height)) { - minX = Math.Max(0, startX); - maxX = Math.Min(width, endX); - minY = Math.Max(0, startY); - maxY = Math.Min(height, endY); - Parallel.For( 0, - sourceHeight, + sourceRectangle.Height, this.ParallelOptions, y => { @@ -154,6 +165,8 @@ namespace ImageSharp.Processors } }); } + + source.SetPixels(width, height, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs index 6a5fd867a..715ab49d5 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // diff --git a/src/ImageSharp/Samplers/Processors/Transforms/ResamplingWeightedProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs similarity index 80% rename from src/ImageSharp/Samplers/Processors/Transforms/ResamplingWeightedProcessor.cs rename to src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs index 808440a0f..4f5efff64 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/ResamplingWeightedProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs @@ -13,21 +13,29 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public abstract class ResamplingWeightedProcessor : ImageSamplingProcessor + public abstract class ResamplingWeightedProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { /// /// Initializes a new instance of the class. /// - /// - /// The sampler to perform the resize operation. + /// The sampler to perform the resize operation. + /// The target width. + /// The target height. + /// + /// The structure that specifies the portion of the target image object to draw to. /// - protected ResamplingWeightedProcessor(IResampler sampler) + protected ResamplingWeightedProcessor(IResampler sampler, int width, int height, Rectangle resizeRectangle) { Guard.NotNull(sampler, nameof(sampler)); + Guard.MustBeGreaterThan(width, 0, nameof(width)); + Guard.MustBeGreaterThan(height, 0, nameof(height)); this.Sampler = sampler; + this.Width = width; + this.Height = height; + this.ResizeRectangle = resizeRectangle; } /// @@ -35,6 +43,21 @@ namespace ImageSharp.Processors /// public IResampler Sampler { get; } + /// + /// Gets the width. + /// + public int Width { get; } + + /// + /// Gets the height. + /// + public int Height { get; } + + /// + /// Gets the resize rectangle. + /// + public Rectangle ResizeRectangle { get; } + /// /// Gets or sets the horizontal weights. /// @@ -46,22 +69,12 @@ namespace ImageSharp.Processors protected Weights[] VerticalWeights { get; set; } /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (!(this.Sampler is NearestNeighborResampler)) { - this.HorizontalWeights = this.PrecomputeWeights(targetRectangle.Width, sourceRectangle.Width); - this.VerticalWeights = this.PrecomputeWeights(targetRectangle.Height, sourceRectangle.Height); - } - } - - /// - protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - // Copy the pixels over. - if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle) - { - target.ClonePixels(target.Width, target.Height, source.Pixels); + this.HorizontalWeights = this.PrecomputeWeights(this.ResizeRectangle.Width, sourceRectangle.Width); + this.VerticalWeights = this.PrecomputeWeights(this.ResizeRectangle.Height, sourceRectangle.Height); } } diff --git a/src/ImageSharp/Samplers/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs similarity index 69% rename from src/ImageSharp/Samplers/Processors/Transforms/ResizeProcessor.cs rename to src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs index 1ec56d6d5..cf0cf2a8f 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs @@ -24,46 +24,61 @@ namespace ImageSharp.Processors /// /// Initializes a new instance of the class. /// - /// - /// The sampler to perform the resize operation. + /// The sampler to perform the resize operation. + /// The target width. + /// The target height. + public ResizeProcessor(IResampler sampler, int width, int height) + : base(sampler, width, height, new Rectangle(0, 0, width, height)) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The sampler to perform the resize operation. + /// The target width. + /// The target height. + /// + /// The structure that specifies the portion of the target image object to draw to. /// - public ResizeProcessor(IResampler sampler) - : base(sampler) + public ResizeProcessor(IResampler sampler, int width, int height, Rectangle resizeRectangle) + : base(sampler, width, height, resizeRectangle) { } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { // Jump out, we'll deal with that later. - if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle) + if (source.Width == this.Width && source.Height == this.Height && sourceRectangle == this.ResizeRectangle) { return; } - int width = target.Width; - int height = target.Height; - int sourceHeight = sourceRectangle.Height; - int targetX = target.Bounds.X; - int targetY = target.Bounds.Y; - int targetRight = target.Bounds.Right; - int targetBottom = target.Bounds.Bottom; - int startX = targetRectangle.X; - int endX = targetRectangle.Right; - - int minX = Math.Max(targetX, startX); - int maxX = Math.Min(targetRight, endX); - int minY = Math.Max(targetY, startY); - int maxY = Math.Min(targetBottom, endY); + // Reset the values as the rectangle can be altered by ResizeRectangle. + startY = this.ResizeRectangle.Y; + endY = this.ResizeRectangle.Bottom; + + int width = this.Width; + int height = this.Height; + int startX = this.ResizeRectangle.X; + int endX = this.ResizeRectangle.Right; + + int minX = Math.Max(0, startX); + int maxX = Math.Min(width, endX); + int minY = Math.Max(0, startY); + int maxY = Math.Min(height, endY); + + TColor[] target = new TColor[width * height]; if (this.Sampler is NearestNeighborResampler) { // Scaling factors - float widthFactor = sourceRectangle.Width / (float)targetRectangle.Width; - float heightFactor = sourceRectangle.Height / (float)targetRectangle.Height; + float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width; + float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( minY, @@ -83,6 +98,7 @@ namespace ImageSharp.Processors } // Break out now. + source.SetPixels(width, height, target); return; } @@ -90,19 +106,14 @@ namespace ImageSharp.Processors // A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm // First process the columns. Since we are not using multiple threads startY and endY // are the upper and lower bounds of the source rectangle. - Image firstPass = new Image(target.Width, source.Height); + TColor[] firstPass = new TColor[width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor firstPassPixels = firstPass.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor firstPassPixels = firstPass.Lock(width, source.Height)) + using (PixelAccessor targetPixels = target.Lock(width, height)) { - minX = Math.Max(0, startX); - maxX = Math.Min(width, endX); - minY = Math.Max(0, startY); - maxY = Math.Min(height, endY); - Parallel.For( 0, - sourceHeight, + sourceRectangle.Height, this.ParallelOptions, y => { @@ -153,6 +164,8 @@ namespace ImageSharp.Processors } }); } + + source.SetPixels(width, height, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Filters/Transforms/EntropyCrop.cs b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs index 17fb109ee..49757039f 100644 --- a/src/ImageSharp/Filters/Transforms/EntropyCrop.cs +++ b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // diff --git a/src/ImageSharp/Samplers/Transforms/Resize.cs b/src/ImageSharp/Filters/Transforms/Resize.cs similarity index 98% rename from src/ImageSharp/Samplers/Transforms/Resize.cs rename to src/ImageSharp/Filters/Transforms/Resize.cs index ee3da5ec6..4c3543c83 100644 --- a/src/ImageSharp/Samplers/Transforms/Resize.cs +++ b/src/ImageSharp/Filters/Transforms/Resize.cs @@ -155,14 +155,14 @@ namespace ImageSharp if (compand) { - processor = new CompandingResizeProcessor(sampler); + processor = new CompandingResizeProcessor(sampler, width, height, targetRectangle); } else { - processor = new ResizeProcessor(sampler); + processor = new ResizeProcessor(sampler, width, height, targetRectangle); } - return source.Process(width, height, sourceRectangle, targetRectangle, processor); + return source.Process(sourceRectangle, processor); } } } diff --git a/tests/ImageSharp.Tests/Processors/Samplers/ResizeTests.cs b/tests/ImageSharp.Tests/Processors/Samplers/ResizeTests.cs index 876ba7ebc..b29ab0116 100644 --- a/tests/ImageSharp.Tests/Processors/Samplers/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processors/Samplers/ResizeTests.cs @@ -5,6 +5,7 @@ namespace ImageSharp.Tests { + using System; using System.IO; using Xunit; @@ -248,7 +249,7 @@ namespace ImageSharp.Tests ResizeOptions options = new ResizeOptions() { Sampler = sampler, - Size = new Size(image.Width - 50, image.Height - 25), + Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * 95F)), Mode = ResizeMode.Min }; @@ -276,7 +277,7 @@ namespace ImageSharp.Tests ResizeOptions options = new ResizeOptions() { Sampler = sampler, - Size = new Size(image.Width - 200, image.Height), + Size = new Size(image.Width / 2, image.Height), Mode = ResizeMode.Stretch }; From 7836a47a429087dfd1f571610b72a06520abc604 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 01:56:45 +1100 Subject: [PATCH 06/15] Trim whitespace --- src/ImageSharp/Colors/Vector4BlendTransforms.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Colors/Vector4BlendTransforms.cs b/src/ImageSharp/Colors/Vector4BlendTransforms.cs index b1d6ebb8c..870d65388 100644 --- a/src/ImageSharp/Colors/Vector4BlendTransforms.cs +++ b/src/ImageSharp/Colors/Vector4BlendTransforms.cs @@ -186,7 +186,7 @@ namespace ImageSharp } /// - /// Linearly interpolates from one vector to another based on the given weighting. + /// Linearly interpolates from one vector to another based on the given weighting. /// The two vectors are premultiplied before operating. /// /// The backdrop vector. @@ -195,7 +195,7 @@ namespace ImageSharp /// A value between 0 and 1 indicating the weight of the second source vector. /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. /// - /// + /// /// The /// public static Vector4 PremultipliedLerp(Vector4 backdrop, Vector4 source, float amount) @@ -216,7 +216,7 @@ namespace ImageSharp // Premultiply the source vector. // Oddly premultiplying the background vector creates dark outlines when pixels - // Have low alpha values. + // Have low alpha values. source = new Vector4(source.X, source.Y, source.Z, 1) * (source.W * amount); // This should be implementing the following formula From 90d78f9cc4c7a3a436f7d1bb6ae0a16bfcbcedba Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 10:01:59 +1100 Subject: [PATCH 07/15] Move tests --- .../ImageSharp.Tests/Processors/{Samplers => Filters}/PadTest.cs | 0 .../Processors/{Samplers => Filters}/ResizeTests.cs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/PadTest.cs (100%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/ResizeTests.cs (100%) diff --git a/tests/ImageSharp.Tests/Processors/Samplers/PadTest.cs b/tests/ImageSharp.Tests/Processors/Filters/PadTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/PadTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/PadTest.cs diff --git a/tests/ImageSharp.Tests/Processors/Samplers/ResizeTests.cs b/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/ResizeTests.cs rename to tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs From 8ea6ad70ab19b72ff182065b1b2d06a4cb992a55 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 10:53:11 +1100 Subject: [PATCH 08/15] Move Rotate and Skew --- .../Transforms/Matrix3x2Processor.cs | 25 ++++---- .../Processors/Transforms/RotateProcessor.cs | 62 ++++++++++--------- .../Processors/Transforms/SkewProcessor.cs | 17 ++--- src/ImageSharp/Samplers/Transforms/Rotate.cs | 2 +- src/ImageSharp/Samplers/Transforms/Skew.cs | 2 +- .../{Samplers => Filters}/RotateTest.cs | 0 .../{Samplers => Filters}/SkewTest.cs | 0 7 files changed, 57 insertions(+), 51 deletions(-) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/RotateTest.cs (100%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/SkewTest.cs (100%) diff --git a/src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs b/src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs index 169441648..e72e8aa61 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs +++ b/src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs @@ -12,38 +12,39 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public abstract class Matrix3x2Processor : ImageSamplingProcessor + public abstract class Matrix3x2Processor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { /// - /// Creates a new target to contain the results of the matrix transform. + /// Gets the rectangle designating the target canvas. + /// + protected Rectangle CanvasRectangle { get; private set; } + + /// + /// Creates a new target canvas to contain the results of the matrix transform. /// - /// Target image to apply the process to. /// The source rectangle. /// The processing matrix. - protected static void CreateNewTarget(ImageBase target, Rectangle sourceRectangle, Matrix3x2 processMatrix) + protected void CreateNewCanvas(Rectangle sourceRectangle, Matrix3x2 processMatrix) { Matrix3x2 sizeMatrix; - if (Matrix3x2.Invert(processMatrix, out sizeMatrix)) - { - Rectangle rectangle = ImageMaths.GetBoundingRectangle(sourceRectangle, sizeMatrix); - target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]); - } + this.CanvasRectangle = Matrix3x2.Invert(processMatrix, out sizeMatrix) + ? ImageMaths.GetBoundingRectangle(sourceRectangle, sizeMatrix) + : sourceRectangle; } /// /// Gets a transform matrix adjusted to center upon the target image bounds. /// - /// Target image to apply the process to. /// The source image. /// The transform matrix. /// /// The . /// - protected static Matrix3x2 GetCenteredMatrix(ImageBase target, ImageBase source, Matrix3x2 matrix) + protected Matrix3x2 GetCenteredMatrix(ImageBase source, Matrix3x2 matrix) { - Matrix3x2 translationToTargetCenter = Matrix3x2.CreateTranslation(-target.Width * .5F, -target.Height * .5F); + Matrix3x2 translationToTargetCenter = Matrix3x2.CreateTranslation(-this.CanvasRectangle.Width * .5F, -this.CanvasRectangle.Height * .5F); Matrix3x2 translateToSourceCenter = Matrix3x2.CreateTranslation(source.Width * .5F, source.Height * .5F); return (translationToTargetCenter * matrix) * translateToSourceCenter; } diff --git a/src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs index a9e69678d..2ab16d592 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs +++ b/src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs @@ -19,7 +19,7 @@ namespace ImageSharp.Processors where TPacked : struct { /// - /// The tranform matrix to apply. + /// The transform matrix to apply. /// private Matrix3x2 processMatrix; @@ -34,19 +34,20 @@ namespace ImageSharp.Processors public bool Expand { get; set; } = true; /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - if (this.OptimizedApply(target, source)) + if (this.OptimizedApply(source)) { return; } - int height = target.Height; - int width = target.Width; - Matrix3x2 matrix = GetCenteredMatrix(target, source, this.processMatrix); + int height = this.CanvasRectangle.Height; + int width = this.CanvasRectangle.Width; + Matrix3x2 matrix = this.GetCenteredMatrix(source, this.processMatrix); + TColor[] target = new TColor[width * height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( 0, @@ -64,10 +65,12 @@ namespace ImageSharp.Processors } }); } + + source.SetPixels(width, height, target); } /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { const float Epsilon = .0001F; @@ -79,40 +82,39 @@ namespace ImageSharp.Processors this.processMatrix = Point.CreateRotation(new Point(0, 0), -this.Angle); if (this.Expand) { - CreateNewTarget(target, sourceRectangle, this.processMatrix); + this.CreateNewCanvas(sourceRectangle, this.processMatrix); } } /// /// Rotates the images with an optimized method when the angle is 90, 180 or 270 degrees. /// - /// The target image. /// The source image. /// The - private bool OptimizedApply(ImageBase target, ImageBase source) + private bool OptimizedApply(ImageBase source) { const float Epsilon = .0001F; if (Math.Abs(this.Angle) < Epsilon) { - target.ClonePixels(target.Width, target.Height, source.Pixels); + // No need to do anything so return. return true; } if (Math.Abs(this.Angle - 90) < Epsilon) { - this.Rotate90(target, source); + this.Rotate90(source); return true; } if (Math.Abs(this.Angle - 180) < Epsilon) { - this.Rotate180(target, source); + this.Rotate180(source); return true; } if (Math.Abs(this.Angle - 270) < Epsilon) { - this.Rotate270(target, source); + this.Rotate270(source); return true; } @@ -122,16 +124,15 @@ namespace ImageSharp.Processors /// /// Rotates the image 270 degrees clockwise at the centre point. /// - /// The target image. /// The source image. - private void Rotate270(ImageBase target, ImageBase source) + private void Rotate270(ImageBase source) { int width = source.Width; int height = source.Height; - Image temp = new Image(height, width); + TColor[] target = new TColor[width * height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor tempPixels = temp.Lock()) + using (PixelAccessor targetPixels = target.Lock(height, width)) { Parallel.For( 0, @@ -144,26 +145,26 @@ namespace ImageSharp.Processors int newX = height - y - 1; newX = height - newX - 1; int newY = width - x - 1; - tempPixels[newX, newY] = sourcePixels[x, y]; + targetPixels[newX, newY] = sourcePixels[x, y]; } }); } - target.SetPixels(height, width, temp.Pixels); + source.SetPixels(height, width, target); } /// /// Rotates the image 180 degrees clockwise at the centre point. /// - /// The target image. /// The source image. - private void Rotate180(ImageBase target, ImageBase source) + private void Rotate180(ImageBase source) { int width = source.Width; int height = source.Height; + TColor[] target = new TColor[width * height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( 0, @@ -179,21 +180,22 @@ namespace ImageSharp.Processors } }); } + + source.SetPixels(width, height, target); } /// /// Rotates the image 90 degrees clockwise at the centre point. /// - /// The target image. /// The source image. - private void Rotate90(ImageBase target, ImageBase source) + private void Rotate90(ImageBase source) { int width = source.Width; int height = source.Height; - Image temp = new Image(height, width); + TColor[] target = new TColor[width * height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor tempPixels = temp.Lock()) + using (PixelAccessor targetPixels = target.Lock(height, width)) { Parallel.For( 0, @@ -204,12 +206,12 @@ namespace ImageSharp.Processors for (int x = 0; x < width; x++) { int newX = height - y - 1; - tempPixels[newX, x] = sourcePixels[x, y]; + targetPixels[newX, x] = sourcePixels[x, y]; } }); } - target.SetPixels(height, width, temp.Pixels); + source.SetPixels(height, width, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Transforms/SkewProcessor.cs b/src/ImageSharp/Samplers/Processors/Transforms/SkewProcessor.cs index 1db363a77..49aa51254 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/SkewProcessor.cs +++ b/src/ImageSharp/Samplers/Processors/Transforms/SkewProcessor.cs @@ -39,14 +39,15 @@ namespace ImageSharp.Processors public bool Expand { get; set; } = true; /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - int height = target.Height; - int width = target.Width; - Matrix3x2 matrix = GetCenteredMatrix(target, source, this.processMatrix); + int height = this.CanvasRectangle.Height; + int width = this.CanvasRectangle.Width; + Matrix3x2 matrix = this.GetCenteredMatrix(source, this.processMatrix); + TColor[] target = new TColor[width * height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( 0, @@ -64,15 +65,17 @@ namespace ImageSharp.Processors } }); } + + source.SetPixels(width, height, target); } /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { this.processMatrix = Point.CreateSkew(new Point(0, 0), -this.AngleX, -this.AngleY); if (this.Expand) { - CreateNewTarget(target, sourceRectangle, this.processMatrix); + this.CreateNewCanvas(sourceRectangle, this.processMatrix); } } } diff --git a/src/ImageSharp/Samplers/Transforms/Rotate.cs b/src/ImageSharp/Samplers/Transforms/Rotate.cs index f8f0a59e8..5815bc0dd 100644 --- a/src/ImageSharp/Samplers/Transforms/Rotate.cs +++ b/src/ImageSharp/Samplers/Transforms/Rotate.cs @@ -56,7 +56,7 @@ namespace ImageSharp where TPacked : struct { RotateProcessor processor = new RotateProcessor { Angle = degrees, Expand = expand }; - return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor); + return source.Process(source.Bounds, processor); } } } diff --git a/src/ImageSharp/Samplers/Transforms/Skew.cs b/src/ImageSharp/Samplers/Transforms/Skew.cs index 4aa756842..cced53c95 100644 --- a/src/ImageSharp/Samplers/Transforms/Skew.cs +++ b/src/ImageSharp/Samplers/Transforms/Skew.cs @@ -43,7 +43,7 @@ namespace ImageSharp where TPacked : struct { SkewProcessor processor = new SkewProcessor { AngleX = degreesX, AngleY = degreesY, Expand = expand }; - return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor); + return source.Process(source.Bounds, processor); } } } diff --git a/tests/ImageSharp.Tests/Processors/Samplers/RotateTest.cs b/tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/RotateTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs diff --git a/tests/ImageSharp.Tests/Processors/Samplers/SkewTest.cs b/tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/SkewTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs From f82e5280041cc4af18582e68f12636a17ff94bf1 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 11:32:50 +1100 Subject: [PATCH 09/15] Move the rest of the transforms --- .../Processors/Transforms/FlipProcessor.cs | 56 ++++++++++--------- .../Transforms/Matrix3x2Processor.cs | 0 .../Processors/Transforms/RotateProcessor.cs | 0 .../Processors/Transforms/SkewProcessor.cs | 0 .../Transforms/AutoOrient.cs | 2 +- .../{Samplers => Filters}/Transforms/Flip.cs | 2 +- .../Transforms/Options/AnchorPosition.cs | 0 .../Transforms/Options/FlipType.cs | 0 .../Transforms/Options/Orientation.cs | 0 .../Transforms/Options/ResizeHelper.cs | 0 .../Transforms/Options/ResizeMode.cs | 0 .../Transforms/Options/ResizeOptions.cs | 0 .../Transforms/Options/RotateType.cs | 0 .../{Samplers => Filters}/Transforms/Pad.cs | 0 .../Transforms/Resamplers/BicubicResampler.cs | 0 .../Transforms/Resamplers/BoxResampler.cs | 0 .../Resamplers/CatmullRomResampler.cs | 0 .../Transforms/Resamplers/HermiteResampler.cs | 0 .../Transforms/Resamplers/IResampler.cs | 0 .../Resamplers/Lanczos2Resampler.cs | 0 .../Resamplers/Lanczos3Resampler.cs | 0 .../Resamplers/Lanczos5Resampler.cs | 0 .../Resamplers/Lanczos8Resampler.cs | 0 .../Resamplers/MitchellNetravaliResampler.cs | 0 .../Resamplers/NearestNeighborResampler.cs | 0 .../Resamplers/RobidouxResampler.cs | 0 .../Resamplers/RobidouxSharpResampler.cs | 0 .../Transforms/Resamplers/SplineResampler.cs | 0 .../Resamplers/TriangleResampler.cs | 0 .../Transforms/Resamplers/WelchResampler.cs | 0 .../Transforms/Rotate.cs | 0 .../Transforms/RotateFlip.cs | 0 .../{Samplers => Filters}/Transforms/Skew.cs | 0 33 files changed, 31 insertions(+), 29 deletions(-) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/FlipProcessor.cs (63%) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/Matrix3x2Processor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/RotateProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Transforms/SkewProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/AutoOrient.cs (97%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Flip.cs (92%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/AnchorPosition.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/FlipType.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/Orientation.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/ResizeHelper.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/ResizeMode.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/ResizeOptions.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Options/RotateType.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Pad.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/BicubicResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/BoxResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/CatmullRomResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/HermiteResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/IResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/Lanczos2Resampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/Lanczos3Resampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/Lanczos5Resampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/Lanczos8Resampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/MitchellNetravaliResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/NearestNeighborResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/RobidouxResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/RobidouxSharpResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/SplineResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/TriangleResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Resamplers/WelchResampler.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Rotate.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/RotateFlip.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Transforms/Skew.cs (100%) diff --git a/src/ImageSharp/Samplers/Processors/Transforms/FlipProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs similarity index 63% rename from src/ImageSharp/Samplers/Processors/Transforms/FlipProcessor.cs rename to src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs index e9464a8ff..b92333251 100644 --- a/src/ImageSharp/Samplers/Processors/Transforms/FlipProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs @@ -13,7 +13,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class FlipProcessor : ImageSamplingProcessor + public class FlipProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -32,18 +32,16 @@ namespace ImageSharp.Processors public FlipType FlipType { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - target.ClonePixels(target.Width, target.Height, source.Pixels); - switch (this.FlipType) { // No default needed as we have already set the pixels. case FlipType.Vertical: - this.FlipX(target); + this.FlipX(source); break; case FlipType.Horizontal: - this.FlipY(target); + this.FlipY(source); break; } } @@ -52,17 +50,17 @@ namespace ImageSharp.Processors /// Swaps the image at the X-axis, which goes horizontally through the middle /// at half the height of the image. /// - /// Target image to apply the process to. - private void FlipX(ImageBase target) + /// The source image to apply the process to. + private void FlipX(ImageBase source) { - int width = target.Width; - int height = target.Height; - int halfHeight = (int)Math.Ceiling(target.Height * .5F); - Image temp = new Image(width, height); - temp.ClonePixels(width, height, target.Pixels); + int width = source.Width; + int height = source.Height; + int halfHeight = (int)Math.Ceiling(source.Height * .5F); + + TColor[] target = new TColor[width * height]; - using (PixelAccessor targetPixels = target.Lock()) - using (PixelAccessor tempPixels = temp.Lock()) + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( 0, @@ -73,28 +71,30 @@ namespace ImageSharp.Processors for (int x = 0; x < width; x++) { int newY = height - y - 1; - targetPixels[x, y] = tempPixels[x, newY]; - targetPixels[x, newY] = tempPixels[x, y]; + targetPixels[x, y] = sourcePixels[x, newY]; + targetPixels[x, newY] = sourcePixels[x, y]; } }); } + + source.SetPixels(width, height, target); } /// /// Swaps the image at the Y-axis, which goes vertically through the middle /// at half of the width of the image. /// - /// Target image to apply the process to. - private void FlipY(ImageBase target) + /// The source image to apply the process to. + private void FlipY(ImageBase source) { - int width = target.Width; - int height = target.Height; + int width = source.Width; + int height = source.Height; int halfWidth = (int)Math.Ceiling(width * .5F); - Image temp = new Image(width, height); - temp.ClonePixels(width, height, target.Pixels); - using (PixelAccessor targetPixels = target.Lock()) - using (PixelAccessor tempPixels = temp.Lock()) + TColor[] target = new TColor[width * height]; + + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( 0, @@ -105,11 +105,13 @@ namespace ImageSharp.Processors for (int x = 0; x < halfWidth; x++) { int newX = width - x - 1; - targetPixels[x, y] = tempPixels[newX, y]; - targetPixels[newX, y] = tempPixels[x, y]; + targetPixels[x, y] = sourcePixels[newX, y]; + targetPixels[newX, y] = sourcePixels[x, y]; } }); } + + source.SetPixels(width, height, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs b/src/ImageSharp/Filters/Processors/Transforms/Matrix3x2Processor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs rename to src/ImageSharp/Filters/Processors/Transforms/Matrix3x2Processor.cs diff --git a/src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs rename to src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Transforms/SkewProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Transforms/SkewProcessor.cs rename to src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs diff --git a/src/ImageSharp/Samplers/Transforms/AutoOrient.cs b/src/ImageSharp/Filters/Transforms/AutoOrient.cs similarity index 97% rename from src/ImageSharp/Samplers/Transforms/AutoOrient.cs rename to src/ImageSharp/Filters/Transforms/AutoOrient.cs index 6195a2066..e7bcbf739 100644 --- a/src/ImageSharp/Samplers/Transforms/AutoOrient.cs +++ b/src/ImageSharp/Filters/Transforms/AutoOrient.cs @@ -11,7 +11,7 @@ namespace ImageSharp public static partial class ImageExtensions { /// - /// Adjusts an image so that its orientation is suitable for viewing. + /// Adjusts an image so that its orientation is suitable for viewing. Adjustments are based on EXIF metadata embedded in the image. /// /// The pixel format. /// The packed format. uint, long, float. diff --git a/src/ImageSharp/Samplers/Transforms/Flip.cs b/src/ImageSharp/Filters/Transforms/Flip.cs similarity index 92% rename from src/ImageSharp/Samplers/Transforms/Flip.cs rename to src/ImageSharp/Filters/Transforms/Flip.cs index 0e50ad8ac..0ea0a9f67 100644 --- a/src/ImageSharp/Samplers/Transforms/Flip.cs +++ b/src/ImageSharp/Filters/Transforms/Flip.cs @@ -25,7 +25,7 @@ namespace ImageSharp where TPacked : struct { FlipProcessor processor = new FlipProcessor(flipType); - return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor); + return source.Process(source.Bounds, processor); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Transforms/Options/AnchorPosition.cs b/src/ImageSharp/Filters/Transforms/Options/AnchorPosition.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/AnchorPosition.cs rename to src/ImageSharp/Filters/Transforms/Options/AnchorPosition.cs diff --git a/src/ImageSharp/Samplers/Transforms/Options/FlipType.cs b/src/ImageSharp/Filters/Transforms/Options/FlipType.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/FlipType.cs rename to src/ImageSharp/Filters/Transforms/Options/FlipType.cs diff --git a/src/ImageSharp/Samplers/Transforms/Options/Orientation.cs b/src/ImageSharp/Filters/Transforms/Options/Orientation.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/Orientation.cs rename to src/ImageSharp/Filters/Transforms/Options/Orientation.cs diff --git a/src/ImageSharp/Samplers/Transforms/Options/ResizeHelper.cs b/src/ImageSharp/Filters/Transforms/Options/ResizeHelper.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/ResizeHelper.cs rename to src/ImageSharp/Filters/Transforms/Options/ResizeHelper.cs diff --git a/src/ImageSharp/Samplers/Transforms/Options/ResizeMode.cs b/src/ImageSharp/Filters/Transforms/Options/ResizeMode.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/ResizeMode.cs rename to src/ImageSharp/Filters/Transforms/Options/ResizeMode.cs diff --git a/src/ImageSharp/Samplers/Transforms/Options/ResizeOptions.cs b/src/ImageSharp/Filters/Transforms/Options/ResizeOptions.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/ResizeOptions.cs rename to src/ImageSharp/Filters/Transforms/Options/ResizeOptions.cs diff --git a/src/ImageSharp/Samplers/Transforms/Options/RotateType.cs b/src/ImageSharp/Filters/Transforms/Options/RotateType.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Options/RotateType.cs rename to src/ImageSharp/Filters/Transforms/Options/RotateType.cs diff --git a/src/ImageSharp/Samplers/Transforms/Pad.cs b/src/ImageSharp/Filters/Transforms/Pad.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Pad.cs rename to src/ImageSharp/Filters/Transforms/Pad.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/BicubicResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/BicubicResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/BicubicResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/BicubicResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/BoxResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/BoxResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/BoxResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/BoxResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/CatmullRomResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/CatmullRomResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/CatmullRomResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/CatmullRomResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/HermiteResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/HermiteResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/HermiteResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/HermiteResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/IResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/IResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/IResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/IResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos2Resampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/Lanczos2Resampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos2Resampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/Lanczos2Resampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos3Resampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/Lanczos3Resampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos3Resampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/Lanczos3Resampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos5Resampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/Lanczos5Resampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos5Resampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/Lanczos5Resampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos8Resampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/Lanczos8Resampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/Lanczos8Resampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/Lanczos8Resampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/MitchellNetravaliResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/MitchellNetravaliResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/MitchellNetravaliResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/MitchellNetravaliResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/NearestNeighborResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/NearestNeighborResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/NearestNeighborResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/NearestNeighborResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/RobidouxResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/RobidouxResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/RobidouxResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/RobidouxResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/RobidouxSharpResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/RobidouxSharpResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/RobidouxSharpResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/RobidouxSharpResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/SplineResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/SplineResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/SplineResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/SplineResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/TriangleResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/TriangleResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/TriangleResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/TriangleResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Resamplers/WelchResampler.cs b/src/ImageSharp/Filters/Transforms/Resamplers/WelchResampler.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Resamplers/WelchResampler.cs rename to src/ImageSharp/Filters/Transforms/Resamplers/WelchResampler.cs diff --git a/src/ImageSharp/Samplers/Transforms/Rotate.cs b/src/ImageSharp/Filters/Transforms/Rotate.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Rotate.cs rename to src/ImageSharp/Filters/Transforms/Rotate.cs diff --git a/src/ImageSharp/Samplers/Transforms/RotateFlip.cs b/src/ImageSharp/Filters/Transforms/RotateFlip.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/RotateFlip.cs rename to src/ImageSharp/Filters/Transforms/RotateFlip.cs diff --git a/src/ImageSharp/Samplers/Transforms/Skew.cs b/src/ImageSharp/Filters/Transforms/Skew.cs similarity index 100% rename from src/ImageSharp/Samplers/Transforms/Skew.cs rename to src/ImageSharp/Filters/Transforms/Skew.cs From 83d2f429bc42b81b84bd2814faf916cb3441dff8 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 11:51:38 +1100 Subject: [PATCH 10/15] Move tests --- .../Processors/{Samplers => Filters}/AutoOrientTests.cs | 0 .../Processors/{Samplers => Filters}/FlipTests.cs | 0 .../Processors/{Samplers => Filters}/RotateFlipTest.cs | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/AutoOrientTests.cs (100%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/FlipTests.cs (100%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/RotateFlipTest.cs (100%) diff --git a/tests/ImageSharp.Tests/Processors/Samplers/AutoOrientTests.cs b/tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/AutoOrientTests.cs rename to tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs diff --git a/tests/ImageSharp.Tests/Processors/Samplers/FlipTests.cs b/tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/FlipTests.cs rename to tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs diff --git a/tests/ImageSharp.Tests/Processors/Samplers/RotateFlipTest.cs b/tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/RotateFlipTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs From 637dce48a8efef2d38731a5897106ea8095f3614 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 12:07:40 +1100 Subject: [PATCH 11/15] Fix spelling.... I can't believe no one spotted this until now! --- .../{GuassianBlur.cs => GaussianBlur.cs} | 14 +++++++------- .../{GuassianSharpen.cs => GaussianSharpen.cs} | 14 +++++++------- ...BlurProcessor.cs => GaussianBlurProcessor.cs} | 16 ++++++++-------- ...nProcessor.cs => GaussianSharpenProcessor.cs} | 16 ++++++++-------- .../{GuassianBlurTest.cs => GaussianBlurTest.cs} | 14 +++++++------- ...sianSharpenTest.cs => GaussianSharpenTest.cs} | 14 +++++++------- 6 files changed, 44 insertions(+), 44 deletions(-) rename src/ImageSharp/Samplers/Convolution/{GuassianBlur.cs => GaussianBlur.cs} (81%) rename src/ImageSharp/Samplers/Convolution/{GuassianSharpen.cs => GaussianSharpen.cs} (80%) rename src/ImageSharp/Samplers/Processors/Convolution/{GuassianBlurProcessor.cs => GaussianBlurProcessor.cs} (90%) rename src/ImageSharp/Samplers/Processors/Convolution/{GuassianSharpenProcessor.cs => GaussianSharpenProcessor.cs} (92%) rename tests/ImageSharp.Tests/Processors/Samplers/{GuassianBlurTest.cs => GaussianBlurTest.cs} (63%) rename tests/ImageSharp.Tests/Processors/Samplers/{GuassianSharpenTest.cs => GaussianSharpenTest.cs} (63%) diff --git a/src/ImageSharp/Samplers/Convolution/GuassianBlur.cs b/src/ImageSharp/Samplers/Convolution/GaussianBlur.cs similarity index 81% rename from src/ImageSharp/Samplers/Convolution/GuassianBlur.cs rename to src/ImageSharp/Samplers/Convolution/GaussianBlur.cs index ef09a18f5..9bc814c5c 100644 --- a/src/ImageSharp/Samplers/Convolution/GuassianBlur.cs +++ b/src/ImageSharp/Samplers/Convolution/GaussianBlur.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -13,22 +13,22 @@ namespace ImageSharp public static partial class ImageExtensions { /// - /// Applies a Guassian blur to the image. + /// Applies a Gaussian blur to the image. /// /// The pixel format. /// The packed format. uint, long, float. /// The image this method extends. /// The 'sigma' value representing the weight of the blur. /// The . - public static Image GuassianBlur(this Image source, float sigma = 3f) + public static Image GaussianBlur(this Image source, float sigma = 3f) where TColor : struct, IPackedPixel where TPacked : struct { - return GuassianBlur(source, sigma, source.Bounds); + return GaussianBlur(source, sigma, source.Bounds); } /// - /// Applies a Guassian blur to the image. + /// Applies a Gaussian blur to the image. /// /// The pixel format. /// The packed format. uint, long, float. @@ -38,11 +38,11 @@ namespace ImageSharp /// The structure that specifies the portion of the image object to alter. /// /// The . - public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle) + public static Image GaussianBlur(this Image source, float sigma, Rectangle rectangle) where TColor : struct, IPackedPixel where TPacked : struct { - return source.Process(rectangle, new GuassianBlurProcessor(sigma)); + return source.Process(rectangle, new GaussianBlurProcessor(sigma)); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Convolution/GuassianSharpen.cs b/src/ImageSharp/Samplers/Convolution/GaussianSharpen.cs similarity index 80% rename from src/ImageSharp/Samplers/Convolution/GuassianSharpen.cs rename to src/ImageSharp/Samplers/Convolution/GaussianSharpen.cs index 6b433f6ae..b3b5efa3f 100644 --- a/src/ImageSharp/Samplers/Convolution/GuassianSharpen.cs +++ b/src/ImageSharp/Samplers/Convolution/GaussianSharpen.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -13,22 +13,22 @@ namespace ImageSharp public static partial class ImageExtensions { /// - /// Applies a Guassian sharpening filter to the image. + /// Applies a Gaussian sharpening filter to the image. /// /// The pixel format. /// The packed format. uint, long, float. /// The image this method extends. /// The 'sigma' value representing the weight of the blur. /// The . - public static Image GuassianSharpen(this Image source, float sigma = 3f) + public static Image GaussianSharpen(this Image source, float sigma = 3f) where TColor : struct, IPackedPixel where TPacked : struct { - return GuassianSharpen(source, sigma, source.Bounds); + return GaussianSharpen(source, sigma, source.Bounds); } /// - /// Applies a Guassian sharpening filter to the image. + /// Applies a Gaussian sharpening filter to the image. /// /// The pixel format. /// The packed format. uint, long, float. @@ -38,11 +38,11 @@ namespace ImageSharp /// The structure that specifies the portion of the image object to alter. /// /// The . - public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle) + public static Image GaussianSharpen(this Image source, float sigma, Rectangle rectangle) where TColor : struct, IPackedPixel where TPacked : struct { - return source.Process(rectangle, new GuassianSharpenProcessor(sigma)); + return source.Process(rectangle, new GaussianSharpenProcessor(sigma)); } } } diff --git a/src/ImageSharp/Samplers/Processors/Convolution/GuassianBlurProcessor.cs b/src/ImageSharp/Samplers/Processors/Convolution/GaussianBlurProcessor.cs similarity index 90% rename from src/ImageSharp/Samplers/Processors/Convolution/GuassianBlurProcessor.cs rename to src/ImageSharp/Samplers/Processors/Convolution/GaussianBlurProcessor.cs index e6af445b4..4025e2125 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/GuassianBlurProcessor.cs +++ b/src/ImageSharp/Samplers/Processors/Convolution/GaussianBlurProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -12,7 +12,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class GuassianBlurProcessor : ImageSamplingProcessor + public class GaussianBlurProcessor : ImageSamplingProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -27,10 +27,10 @@ namespace ImageSharp.Processors private readonly float sigma; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The 'sigma' value representing the weight of the blur. - public GuassianBlurProcessor(float sigma = 3f) + public GaussianBlurProcessor(float sigma = 3f) { this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; this.sigma = sigma; @@ -39,12 +39,12 @@ namespace ImageSharp.Processors } /// - /// 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 GuassianBlurProcessor(int radius) + public GaussianBlurProcessor(int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = radius; @@ -53,7 +53,7 @@ namespace ImageSharp.Processors } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'sigma' value representing the weight of the blur. @@ -62,7 +62,7 @@ namespace ImageSharp.Processors /// The 'radius' value representing the size of the area to sample. /// This should be at least twice the sigma value. /// - public GuassianBlurProcessor(float sigma, int radius) + public GaussianBlurProcessor(float sigma, int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = sigma; diff --git a/src/ImageSharp/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs b/src/ImageSharp/Samplers/Processors/Convolution/GaussianSharpenProcessor.cs similarity index 92% rename from src/ImageSharp/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs rename to src/ImageSharp/Samplers/Processors/Convolution/GaussianSharpenProcessor.cs index 56cf94ea3..2d2a343d3 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs +++ b/src/ImageSharp/Samplers/Processors/Convolution/GaussianSharpenProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -12,7 +12,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class GuassianSharpenProcessor : ImageSamplingProcessor + public class GaussianSharpenProcessor : ImageSamplingProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -27,12 +27,12 @@ namespace ImageSharp.Processors private readonly float sigma; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'sigma' value representing the weight of the sharpening. /// - public GuassianSharpenProcessor(float sigma = 3f) + public GaussianSharpenProcessor(float sigma = 3f) { this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; this.sigma = sigma; @@ -41,12 +41,12 @@ namespace ImageSharp.Processors } /// - /// 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 GuassianSharpenProcessor(int radius) + public GaussianSharpenProcessor(int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = radius; @@ -55,7 +55,7 @@ namespace ImageSharp.Processors } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The 'sigma' value representing the weight of the sharpen. @@ -64,7 +64,7 @@ namespace ImageSharp.Processors /// The 'radius' value representing the size of the area to sample. /// This should be at least twice the sigma value. /// - public GuassianSharpenProcessor(float sigma, int radius) + public GaussianSharpenProcessor(float sigma, int radius) { this.kernelSize = (radius * 2) + 1; this.sigma = sigma; diff --git a/tests/ImageSharp.Tests/Processors/Samplers/GuassianBlurTest.cs b/tests/ImageSharp.Tests/Processors/Samplers/GaussianBlurTest.cs similarity index 63% rename from tests/ImageSharp.Tests/Processors/Samplers/GuassianBlurTest.cs rename to tests/ImageSharp.Tests/Processors/Samplers/GaussianBlurTest.cs index cd1cc5638..6a8279689 100644 --- a/tests/ImageSharp.Tests/Processors/Samplers/GuassianBlurTest.cs +++ b/tests/ImageSharp.Tests/Processors/Samplers/GaussianBlurTest.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -9,9 +9,9 @@ namespace ImageSharp.Tests using Xunit; - public class GuassianBlurTest : FileTestBase + public class GaussianBlurTest : FileTestBase { - public static readonly TheoryData GuassianBlurValues + public static readonly TheoryData GaussianBlurValues = new TheoryData { 3 , @@ -19,10 +19,10 @@ namespace ImageSharp.Tests }; [Theory] - [MemberData("GuassianBlurValues")] - public void ImageShouldApplyGuassianBlurFilter(int value) + [MemberData("GaussianBlurValues")] + public void ImageShouldApplyGaussianBlurFilter(int value) { - string path = CreateOutputDirectory("GuassianBlur"); + string path = CreateOutputDirectory("GaussianBlur"); foreach (TestFile file in Files) { @@ -31,7 +31,7 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { - image.GuassianBlur(value) + image.GaussianBlur(value) .Save(output); } } diff --git a/tests/ImageSharp.Tests/Processors/Samplers/GuassianSharpenTest.cs b/tests/ImageSharp.Tests/Processors/Samplers/GaussianSharpenTest.cs similarity index 63% rename from tests/ImageSharp.Tests/Processors/Samplers/GuassianSharpenTest.cs rename to tests/ImageSharp.Tests/Processors/Samplers/GaussianSharpenTest.cs index 5672b5bae..75e2020cd 100644 --- a/tests/ImageSharp.Tests/Processors/Samplers/GuassianSharpenTest.cs +++ b/tests/ImageSharp.Tests/Processors/Samplers/GaussianSharpenTest.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -9,9 +9,9 @@ namespace ImageSharp.Tests using Xunit; - public class GuassianSharpenTest : FileTestBase + public class GaussianSharpenTest : FileTestBase { - public static readonly TheoryData GuassianSharpenValues + public static readonly TheoryData GaussianSharpenValues = new TheoryData { 3 , @@ -19,10 +19,10 @@ namespace ImageSharp.Tests }; [Theory] - [MemberData("GuassianSharpenValues")] - public void ImageShouldApplyGuassianSharpenFilter(int value) + [MemberData("GaussianSharpenValues")] + public void ImageShouldApplyGaussianSharpenFilter(int value) { - string path = CreateOutputDirectory("GuassianSharpen"); + string path = CreateOutputDirectory("GaussianSharpen"); foreach (TestFile file in Files) { @@ -31,7 +31,7 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { - image.GuassianSharpen(value) + image.GaussianSharpen(value) .Save(output); } } From 40eceb2674347cf5c89fd95ef8737b1e57426c3b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 16:49:01 +1100 Subject: [PATCH 12/15] Move convolution filters --- .../Convolution/BoxBlur.cs | 0 .../Convolution/DetectEdges.cs | 0 .../Convolution/GaussianBlur.cs | 0 .../Convolution/GaussianSharpen.cs | 0 .../Convolution/Options/EdgeDetection.cs | 0 .../Convolution/BoxBlurProcessor.cs | 6 ++-- .../Convolution/Convolution2DProcessor.cs | 13 +++++---- .../Convolution/Convolution2PassProcessor.cs | 28 ++++++++++++------- .../Convolution/ConvolutionProcessor.cs | 12 ++++---- .../EdgeDetection/EdgeDetector2DProcessor.cs | 8 +++--- .../EdgeDetectorCompassProcessor.cs | 18 ++++++++---- .../EdgeDetection/EdgeDetectorProcessor.cs | 10 +++---- .../EdgeDetection/IEdgeDetectorSampler.cs | 2 +- .../EdgeDetection/KayyaliProcessor.cs | 0 .../EdgeDetection/KirschProcessor.cs | 0 .../EdgeDetection/Laplacian3X3Processor.cs | 0 .../EdgeDetection/Laplacian5X5Processor.cs | 0 .../LaplacianOfGaussianProcessor.cs | 0 .../EdgeDetection/PrewittProcessor.cs | 0 .../EdgeDetection/RobertsCrossProcessor.cs | 0 .../EdgeDetection/RobinsonProcessor.cs | 0 .../EdgeDetection/ScharrProcessor.cs | 0 .../EdgeDetection/SobelProcessor.cs | 0 .../Convolution/GaussianBlurProcessor.cs | 6 ++-- .../Convolution/GaussianSharpenProcessor.cs | 6 ++-- .../Transforms/EntropyCropProcessor.cs | 3 +- .../{Samplers => Filters}/DetectEdgesTest.cs | 6 ++-- .../{Samplers => Filters}/EntropyCropTest.cs | 0 .../{Samplers => Filters}/GaussianBlurTest.cs | 0 .../GaussianSharpenTest.cs | 0 30 files changed, 70 insertions(+), 48 deletions(-) rename src/ImageSharp/{Samplers => Filters}/Convolution/BoxBlur.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Convolution/DetectEdges.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Convolution/GaussianBlur.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Convolution/GaussianSharpen.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Convolution/Options/EdgeDetection.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/BoxBlurProcessor.cs (89%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/Convolution2DProcessor.cs (92%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/Convolution2PassProcessor.cs (78%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/ConvolutionProcessor.cs (89%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs (75%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs (84%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs (74%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs (94%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/KirschProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/PrewittProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/ScharrProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/EdgeDetection/SobelProcessor.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/GaussianBlurProcessor.cs (92%) rename src/ImageSharp/{Samplers => Filters}/Processors/Convolution/GaussianSharpenProcessor.cs (94%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/DetectEdgesTest.cs (94%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/EntropyCropTest.cs (100%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/GaussianBlurTest.cs (100%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/GaussianSharpenTest.cs (100%) diff --git a/src/ImageSharp/Samplers/Convolution/BoxBlur.cs b/src/ImageSharp/Filters/Convolution/BoxBlur.cs similarity index 100% rename from src/ImageSharp/Samplers/Convolution/BoxBlur.cs rename to src/ImageSharp/Filters/Convolution/BoxBlur.cs diff --git a/src/ImageSharp/Samplers/Convolution/DetectEdges.cs b/src/ImageSharp/Filters/Convolution/DetectEdges.cs similarity index 100% rename from src/ImageSharp/Samplers/Convolution/DetectEdges.cs rename to src/ImageSharp/Filters/Convolution/DetectEdges.cs diff --git a/src/ImageSharp/Samplers/Convolution/GaussianBlur.cs b/src/ImageSharp/Filters/Convolution/GaussianBlur.cs similarity index 100% rename from src/ImageSharp/Samplers/Convolution/GaussianBlur.cs rename to src/ImageSharp/Filters/Convolution/GaussianBlur.cs diff --git a/src/ImageSharp/Samplers/Convolution/GaussianSharpen.cs b/src/ImageSharp/Filters/Convolution/GaussianSharpen.cs similarity index 100% rename from src/ImageSharp/Samplers/Convolution/GaussianSharpen.cs rename to src/ImageSharp/Filters/Convolution/GaussianSharpen.cs diff --git a/src/ImageSharp/Samplers/Convolution/Options/EdgeDetection.cs b/src/ImageSharp/Filters/Convolution/Options/EdgeDetection.cs similarity index 100% rename from src/ImageSharp/Samplers/Convolution/Options/EdgeDetection.cs rename to src/ImageSharp/Filters/Convolution/Options/EdgeDetection.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs similarity index 89% rename from src/ImageSharp/Samplers/Processors/Convolution/BoxBlurProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs index a8ff27aaf..efe5fcf7e 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/BoxBlurProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class BoxBlurProcessor : ImageSamplingProcessor + public class BoxBlurProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -43,9 +43,9 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } /// diff --git a/src/ImageSharp/Samplers/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs similarity index 92% rename from src/ImageSharp/Samplers/Processors/Convolution/Convolution2DProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs index 61b86c5d1..c0d23adf1 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs @@ -14,7 +14,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class Convolution2DProcessor : ImageSamplingProcessor + public class Convolution2DProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -40,7 +40,7 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { int kernelYHeight = this.KernelY.Length; int kernelYWidth = this.KernelY[0].Length; @@ -56,8 +56,10 @@ namespace ImageSharp.Processors int maxY = sourceBottom - 1; int maxX = endX - 1; + + TColor[] target = new TColor[source.Width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(source.Width, source.Height)) { Parallel.For( startY, @@ -116,14 +118,15 @@ namespace ImageSharp.Processors float green = (float)Math.Sqrt((gX * gX) + (gY * gY)); float blue = (float)Math.Sqrt((bX * bX) + (bY * bY)); - Vector4 targetColor = targetPixels[x, y].ToVector4(); TColor packed = default(TColor); - packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z)); + packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); targetPixels[x, y] = packed; } } }); } + + source.SetPixels(source.Width, source.Height, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs similarity index 78% rename from src/ImageSharp/Samplers/Processors/Convolution/Convolution2PassProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs index 428ef9484..42e48cf42 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs @@ -13,7 +13,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class Convolution2PassProcessor : ImageSamplingProcessor + public class Convolution2PassProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -39,29 +39,37 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { float[][] kernelX = this.KernelX; float[][] kernelY = this.KernelY; + int width = source.Width; + int height = source.Height; - ImageBase firstPass = new Image(source.Width, source.Height); - this.ApplyConvolution(firstPass, source, sourceRectangle, startY, endY, kernelX); - this.ApplyConvolution(target, firstPass, sourceRectangle, startY, endY, kernelY); + TColor[] target = new TColor[width * height]; + TColor[] firstPass = new TColor[width * height]; + + this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, startY, endY, kernelX); + this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, startY, endY, kernelY); + + source.SetPixels(width, height, target); } /// /// Applies the process to the specified portion of the specified at the specified location /// and with the specified size. /// - /// Target image to apply the process to. - /// The source image. Cannot be null. + /// The image width. + /// The image height. + /// The target pixels to apply the process to. + /// The source pixels. Cannot be null. /// /// The structure that specifies the portion of the image object to draw. /// /// The index of the row within the source image to start processing. /// The index of the row within the source image to end processing. /// The kernel operator. - private void ApplyConvolution(ImageBase target, ImageBase source, Rectangle sourceRectangle, int startY, int endY, float[][] kernel) + private void ApplyConvolution(int width, int height, TColor[] target, TColor[] source, Rectangle sourceRectangle, int startY, int endY, float[][] kernel) { int kernelHeight = kernel.Length; int kernelWidth = kernel[0].Length; @@ -74,8 +82,8 @@ namespace ImageSharp.Processors int maxY = sourceBottom - 1; int maxX = endX - 1; - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor sourcePixels = source.Lock(width, height)) + using (PixelAccessor targetPixels = target.Lock(width, height)) { Parallel.For( startY, diff --git a/src/ImageSharp/Samplers/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs similarity index 89% rename from src/ImageSharp/Samplers/Processors/Convolution/ConvolutionProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs index d9252a22d..f7664904e 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs @@ -13,7 +13,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class ConvolutionProcessor : ImageSamplingProcessor + public class ConvolutionProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -32,7 +32,7 @@ namespace ImageSharp.Processors public virtual float[][] KernelXY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { float[][] kernelX = this.KernelXY; int kernelLength = kernelX.GetLength(0); @@ -45,8 +45,9 @@ namespace ImageSharp.Processors int maxY = sourceBottom - 1; int maxX = endX - 1; + TColor[] target = new TColor[source.Width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(source.Width, source.Height)) { Parallel.For( startY, @@ -92,14 +93,15 @@ namespace ImageSharp.Processors float green = gX; float blue = bX; - Vector4 targetColor = targetPixels[x, y].ToVector4(); TColor packed = default(TColor); - packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z)); + packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); targetPixels[x, y] = packed; } } }); } + + source.SetPixels(source.Width, source.Height, target); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs similarity index 75% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs index c247d9a99..0acb69980 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public abstract class EdgeDetector2DProcessor : ImageSamplingProcessor, IEdgeDetectorProcessor + public abstract class EdgeDetector2DProcessor : ImageFilteringProcessor, IEdgeDetectorProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -28,13 +28,13 @@ namespace ImageSharp.Processors public bool Grayscale { get; set; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - new Convolution2DProcessor(this.KernelX, this.KernelY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + new Convolution2DProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (this.Grayscale) { diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs similarity index 84% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs index 1ae9e48bb..59cf63242 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs @@ -14,7 +14,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public abstract class EdgeDetectorCompassProcessor : ImageSamplingProcessor, IEdgeDetectorProcessor + public abstract class EdgeDetectorCompassProcessor : ImageFilteringProcessor, IEdgeDetectorProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -62,7 +62,7 @@ namespace ImageSharp.Processors public bool Grayscale { get; set; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { float[][][] kernels = { this.North, this.NorthWest, this.West, this.SouthWest, this.South, this.SouthEast, this.East, this.NorthEast }; @@ -76,7 +76,9 @@ namespace ImageSharp.Processors int maxY = Math.Min(source.Height, endY); // First run. - new ConvolutionProcessor(kernels[0]).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + ImageBase target = new Image(source.Width, source.Height); + target.ClonePixels(source.Width, source.Height, source.Pixels); + new ConvolutionProcessor(kernels[0]).Apply(target, sourceRectangle); if (kernels.Length == 1) { @@ -98,10 +100,14 @@ namespace ImageSharp.Processors } // Additional runs. + // ReSharper disable once ForCanBeConvertedToForeach for (int i = 1; i < kernels.Length; i++) { + // Create a clone for each pass and copy the offset pixels across. ImageBase pass = new Image(source.Width, source.Height); - new ConvolutionProcessor(kernels[i]).Apply(pass, source, sourceRectangle, targetRectangle, startY, endY); + pass.ClonePixels(source.Width, source.Height, source.Pixels); + + new ConvolutionProcessor(kernels[i]).Apply(pass, sourceRectangle); using (PixelAccessor passPixels = pass.Lock()) using (PixelAccessor targetPixels = target.Lock()) @@ -125,10 +131,12 @@ namespace ImageSharp.Processors }); } } + + source.SetPixels(source.Width, source.Height, target.Pixels); } /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (this.Grayscale) { diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs similarity index 74% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs index 734d18114..847f3a1c7 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public abstract class EdgeDetectorProcessor : ImageSamplingProcessor, IEdgeDetectorProcessor + public abstract class EdgeDetectorProcessor : ImageFilteringProcessor, IEdgeDetectorProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -23,13 +23,13 @@ namespace ImageSharp.Processors public abstract float[][] KernelXY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - new ConvolutionProcessor(this.KernelXY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + new ConvolutionProcessor(this.KernelXY).Apply(source, sourceRectangle); } /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { if (this.Grayscale) { @@ -37,4 +37,4 @@ namespace ImageSharp.Processors } } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs similarity index 94% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs index ac1c5a6fa..65abc525f 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public interface IEdgeDetectorProcessor : IImageSamplingProcessor, IEdgeDetectorProcessor + public interface IEdgeDetectorProcessor : IImageFilteringProcessor, IEdgeDetectorProcessor where TColor : struct, IPackedPixel where TPacked : struct { diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs similarity index 100% rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs diff --git a/src/ImageSharp/Samplers/Processors/Convolution/GaussianBlurProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs similarity index 92% rename from src/ImageSharp/Samplers/Processors/Convolution/GaussianBlurProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs index 4025e2125..8553e4264 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/GaussianBlurProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs @@ -12,7 +12,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class GaussianBlurProcessor : ImageSamplingProcessor + public class GaussianBlurProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -81,9 +81,9 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } /// diff --git a/src/ImageSharp/Samplers/Processors/Convolution/GaussianSharpenProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs similarity index 94% rename from src/ImageSharp/Samplers/Processors/Convolution/GaussianSharpenProcessor.cs rename to src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs index 2d2a343d3..48790a733 100644 --- a/src/ImageSharp/Samplers/Processors/Convolution/GaussianSharpenProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs @@ -12,7 +12,7 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class GaussianSharpenProcessor : ImageSamplingProcessor + public class GaussianSharpenProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { @@ -83,9 +83,9 @@ namespace ImageSharp.Processors public float[][] KernelY { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { - new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle); } /// diff --git a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs index 715ab49d5..263c63790 100644 --- a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs @@ -37,9 +37,10 @@ namespace ImageSharp.Processors protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { ImageBase temp = new Image(source.Width, source.Height); + temp.ClonePixels(source.Width, source.Height, source.Pixels); // Detect the edges. - new SobelProcessor().Apply(temp, source, sourceRectangle); + new SobelProcessor().Apply(temp, sourceRectangle); // Apply threshold binarization filter. new BinaryThresholdProcessor(this.Value).Apply(temp, sourceRectangle); diff --git a/tests/ImageSharp.Tests/Processors/Samplers/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs similarity index 94% rename from tests/ImageSharp.Tests/Processors/Samplers/DetectEdgesTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs index ce088eac4..a650f85dd 100644 --- a/tests/ImageSharp.Tests/Processors/Samplers/DetectEdgesTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs @@ -23,7 +23,7 @@ namespace ImageSharp.Tests EdgeDetection.RobertsCross, EdgeDetection.Robinson, EdgeDetection.Scharr, - EdgeDetection.Sobel, + EdgeDetection.Sobel }; [Theory] @@ -40,7 +40,7 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { image.DetectEdges(detector) - .Save(output); + .Save(output); } } } @@ -59,7 +59,7 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { image.DetectEdges(detector, new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2)) - .Save(output); + .Save(output); } } } diff --git a/tests/ImageSharp.Tests/Processors/Samplers/EntropyCropTest.cs b/tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/EntropyCropTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs diff --git a/tests/ImageSharp.Tests/Processors/Samplers/GaussianBlurTest.cs b/tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/GaussianBlurTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs diff --git a/tests/ImageSharp.Tests/Processors/Samplers/GaussianSharpenTest.cs b/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs similarity index 100% rename from tests/ImageSharp.Tests/Processors/Samplers/GaussianSharpenTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs From 7e380fe89b6ba446ed3ebaf53f8089d2c3f46ddc Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 17:02:12 +1100 Subject: [PATCH 13/15] Move Oilpaint --- .../Effects/OilPainting.cs | 0 .../Processors/Effects/OilPaintingProcessor.cs | 14 ++++++++------ .../{Samplers => Filters}/OilPaintTest.cs | 18 ++++++++++++------ 3 files changed, 20 insertions(+), 12 deletions(-) rename src/ImageSharp/{Samplers => Filters}/Effects/OilPainting.cs (100%) rename src/ImageSharp/{Samplers => Filters}/Processors/Effects/OilPaintingProcessor.cs (92%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/OilPaintTest.cs (70%) diff --git a/src/ImageSharp/Samplers/Effects/OilPainting.cs b/src/ImageSharp/Filters/Effects/OilPainting.cs similarity index 100% rename from src/ImageSharp/Samplers/Effects/OilPainting.cs rename to src/ImageSharp/Filters/Effects/OilPainting.cs diff --git a/src/ImageSharp/Samplers/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs similarity index 92% rename from src/ImageSharp/Samplers/Processors/Effects/OilPaintingProcessor.cs rename to src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs index 77b7a158f..f368152fc 100644 --- a/src/ImageSharp/Samplers/Processors/Effects/OilPaintingProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs @@ -15,12 +15,12 @@ namespace ImageSharp.Processors /// Adapted from by Dewald Esterhuizen. /// The pixel format. /// The packed format. uint, long, float. - public class OilPaintingProcessor : ImageSamplingProcessor + public class OilPaintingProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The number of intensity levels. Higher values result in a broader range of color intensities forming part of the result image. @@ -48,7 +48,7 @@ namespace ImageSharp.Processors public int BrushSize { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { int startX = sourceRectangle.X; int endX = sourceRectangle.Right; @@ -67,8 +67,9 @@ namespace ImageSharp.Processors startX = 0; } + TColor[] target = new TColor[source.Width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(source.Width, source.Height)) { Parallel.For( minY, @@ -142,14 +143,15 @@ namespace ImageSharp.Processors float green = Math.Abs(greenBin[maxIndex] / maxIntensity); float blue = Math.Abs(blueBin[maxIndex] / maxIntensity); - Vector4 targetColor = targetPixels[x, y].ToVector4(); TColor packed = default(TColor); - packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z)); + packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); targetPixels[x, y] = packed; } } }); } + + source.SetPixels(source.Width, source.Height, target); } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Samplers/OilPaintTest.cs b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs similarity index 70% rename from tests/ImageSharp.Tests/Processors/Samplers/OilPaintTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs index 8b5ff3f51..e6fa22a6f 100644 --- a/tests/ImageSharp.Tests/Processors/Samplers/OilPaintTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs @@ -15,8 +15,8 @@ namespace ImageSharp.Tests public static readonly TheoryData> OilPaintValues = new TheoryData> { - new Tuple(15,10), - new Tuple(6,5) + new Tuple(15, 10), + new Tuple(8, 5) }; [Theory] @@ -32,8 +32,11 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { - image.OilPaint(value.Item1, value.Item2) - .Save(output); + if (value.Item2 < image.Width && value.Item2 < image.Height) + { + image.OilPaint(value.Item1, value.Item2) + .Save(output); + } } } } @@ -51,8 +54,11 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { - image.OilPaint(value.Item1, value.Item2, new Rectangle(10, 10, image.Width / 2, image.Height / 2)) - .Save(output); + if (value.Item2 < image.Width && value.Item2 < image.Height) + { + image.OilPaint(value.Item1, value.Item2, new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2)) + .Save(output); + } } } } From 3d11434205b8f2f852500697849ff859e086ef0b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 17:10:45 +1100 Subject: [PATCH 14/15] Move pixelate --- .../{Samplers => Filters}/Effects/Pixelate.cs | 2 +- .../Processors/Effects/PixelateProcessor.cs} | 15 +++++++++------ .../{Samplers => Filters}/PixelateTest.cs | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) rename src/ImageSharp/{Samplers => Filters}/Effects/Pixelate.cs (98%) rename src/ImageSharp/{Samplers/Processors/Effects/PixelateProcesso.cs => Filters/Processors/Effects/PixelateProcessor.cs} (87%) rename tests/ImageSharp.Tests/Processors/{Samplers => Filters}/PixelateTest.cs (95%) diff --git a/src/ImageSharp/Samplers/Effects/Pixelate.cs b/src/ImageSharp/Filters/Effects/Pixelate.cs similarity index 98% rename from src/ImageSharp/Samplers/Effects/Pixelate.cs rename to src/ImageSharp/Filters/Effects/Pixelate.cs index 627ad80bb..e7bd84c31 100644 --- a/src/ImageSharp/Samplers/Effects/Pixelate.cs +++ b/src/ImageSharp/Filters/Effects/Pixelate.cs @@ -49,7 +49,7 @@ namespace ImageSharp throw new ArgumentOutOfRangeException(nameof(size)); } - return source.Process(rectangle, new PixelateProcesso(size)); + return source.Process(rectangle, new PixelateProcessor(size)); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Effects/PixelateProcesso.cs b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs similarity index 87% rename from src/ImageSharp/Samplers/Processors/Effects/PixelateProcesso.cs rename to src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs index 41775ed97..347dc39c9 100644 --- a/src/ImageSharp/Samplers/Processors/Effects/PixelateProcesso.cs +++ b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -14,18 +14,18 @@ namespace ImageSharp.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class PixelateProcesso : ImageSamplingProcessor + public class PixelateProcessor : ImageFilteringProcessor where TColor : struct, IPackedPixel where TPacked : struct { /// - /// Initializes a new instance of the class. + /// 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 PixelateProcesso(int size) + public PixelateProcessor(int size) { Guard.MustBeGreaterThan(size, 0, nameof(size)); this.Value = size; @@ -37,7 +37,7 @@ namespace ImageSharp.Processors public int Value { get; } /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) { int startX = sourceRectangle.X; int endX = sourceRectangle.Right; @@ -63,9 +63,10 @@ namespace ImageSharp.Processors // Get the range on the y-plane to choose from. IEnumerable range = EnumerableExtensions.SteppedRange(minY, i => i < maxY, size); + TColor[] target = new TColor[source.Width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) + using (PixelAccessor targetPixels = target.Lock(source.Width, source.Height)) { Parallel.ForEach( range, @@ -105,6 +106,8 @@ namespace ImageSharp.Processors } } }); + + source.SetPixels(source.Width, source.Height, target); } } } diff --git a/tests/ImageSharp.Tests/Processors/Samplers/PixelateTest.cs b/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs similarity index 95% rename from tests/ImageSharp.Tests/Processors/Samplers/PixelateTest.cs rename to tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs index 397bdef06..8655dfb96 100644 --- a/tests/ImageSharp.Tests/Processors/Samplers/PixelateTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs @@ -32,7 +32,7 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { image.Pixelate(value) - .Save(output); + .Save(output); } } } @@ -51,7 +51,7 @@ namespace ImageSharp.Tests using (FileStream output = File.OpenWrite($"{path}/{filename}")) { image.Pixelate(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)) - .Save(output); + .Save(output); } } } From b3417bb0d6e3f844af00e067de59be096c10a814 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 9 Dec 2016 17:20:42 +1100 Subject: [PATCH 15/15] Cleanup sampler methods. --- .../Filters/Convolution/DetectEdges.cs | 2 +- src/ImageSharp/Filters/Effects/Pixelate.cs | 55 -------- .../Convolution/Convolution2DProcessor.cs | 1 - ...orSampler.cs => IEdgeDetectorProcessor.cs} | 0 .../EdgeDetection/KayyaliProcessor.cs | 2 +- .../Effects/OilPaintingProcessor.cs | 2 +- .../Processors/Effects/PixelateProcessor.cs | 2 +- .../Filters/Transforms/EntropyCrop.cs | 1 - src/ImageSharp/IO/EndianBinaryReader.cs | 12 +- .../Image/ImageProcessingExtensions.cs | 130 ------------------ .../Processors/IImageSamplingProcessor.cs | 58 -------- .../Processors/ImageSamplingProcessor.cs | 119 ---------------- .../Processors/Filters/GaussianSharpenTest.cs | 2 +- .../Processors/Filters/OilPaintTest.cs | 66 --------- .../Processors/Filters/PixelateTest.cs | 59 -------- 15 files changed, 14 insertions(+), 497 deletions(-) rename src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/{IEdgeDetectorSampler.cs => IEdgeDetectorProcessor.cs} (100%) delete mode 100644 src/ImageSharp/Samplers/Processors/IImageSamplingProcessor.cs delete mode 100644 src/ImageSharp/Samplers/Processors/ImageSamplingProcessor.cs diff --git a/src/ImageSharp/Filters/Convolution/DetectEdges.cs b/src/ImageSharp/Filters/Convolution/DetectEdges.cs index 649e0cf64..3ddcc6672 100644 --- a/src/ImageSharp/Filters/Convolution/DetectEdges.cs +++ b/src/ImageSharp/Filters/Convolution/DetectEdges.cs @@ -82,7 +82,7 @@ namespace ImageSharp switch (filter) { case EdgeDetection.Kayyali: - processor = new KayyaliSampler { Grayscale = grayscale }; + processor = new KayyaliProcessor { Grayscale = grayscale }; break; case EdgeDetection.Kirsch: diff --git a/src/ImageSharp/Filters/Effects/Pixelate.cs b/src/ImageSharp/Filters/Effects/Pixelate.cs index e7bd84c31..e69de29bb 100644 --- a/src/ImageSharp/Filters/Effects/Pixelate.cs +++ b/src/ImageSharp/Filters/Effects/Pixelate.cs @@ -1,55 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp -{ - using System; - - using Processors; - - /// - /// Extension methods for the type. - /// - public static partial class ImageExtensions - { - /// - /// Pixelates an image with the given pixel size. - /// - /// The pixel format. - /// The packed format. uint, long, float. - /// The image this method extends. - /// The size of the pixels. - /// The . - public static Image Pixelate(this Image source, int size = 4) - where TColor : struct, IPackedPixel - where TPacked : struct - { - return Pixelate(source, size, source.Bounds); - } - - /// - /// Pixelates an image with the given pixel size. - /// - /// The pixel format. - /// The packed format. uint, long, float. - /// The image this method extends. - /// The size of the pixels. - /// - /// The structure that specifies the portion of the image object to alter. - /// - /// The . - public static Image Pixelate(this Image source, int size, Rectangle rectangle) - where TColor : struct, IPackedPixel - where TPacked : struct - { - if (size <= 0 || size > source.Height || size > source.Width) - { - throw new ArgumentOutOfRangeException(nameof(size)); - } - - return source.Process(rectangle, new PixelateProcessor(size)); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs index c0d23adf1..afebcd8ed 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs @@ -56,7 +56,6 @@ namespace ImageSharp.Processors int maxY = sourceBottom - 1; int maxX = endX - 1; - TColor[] target = new TColor[source.Width * source.Height]; using (PixelAccessor sourcePixels = source.Lock()) using (PixelAccessor targetPixels = target.Lock(source.Width, source.Height)) diff --git a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs similarity index 100% rename from src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs diff --git a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs index 5fbf54b30..039836230 100644 --- a/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs @@ -14,7 +14,7 @@ namespace ImageSharp.Processors /// The pixel format. /// The packed format. uint, long, float. [SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")] - public class KayyaliSampler : EdgeDetector2DProcessor + public class KayyaliProcessor : EdgeDetector2DProcessor where TColor : struct, IPackedPixel where TPacked : struct { diff --git a/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs index f368152fc..cddf74af6 100644 --- a/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Processors using System.Threading.Tasks; /// - /// An to apply an oil painting effect to an . + /// An to apply an oil painting effect to an . /// /// Adapted from by Dewald Esterhuizen. /// The pixel format. diff --git a/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs index 347dc39c9..17b0450e0 100644 --- a/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs +++ b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs @@ -10,7 +10,7 @@ namespace ImageSharp.Processors using System.Threading.Tasks; /// - /// An to pixelate the colors of an . + /// An to pixelate the colors of an . /// /// The pixel format. /// The packed format. uint, long, float. diff --git a/src/ImageSharp/Filters/Transforms/EntropyCrop.cs b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs index 49757039f..06902888d 100644 --- a/src/ImageSharp/Filters/Transforms/EntropyCrop.cs +++ b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs @@ -26,7 +26,6 @@ namespace ImageSharp { EntropyCropProcessor processor = new EntropyCropProcessor(threshold); return source.Process(source.Bounds, processor); - // return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor); } } } \ No newline at end of file diff --git a/src/ImageSharp/IO/EndianBinaryReader.cs b/src/ImageSharp/IO/EndianBinaryReader.cs index 3b12401b6..105647675 100644 --- a/src/ImageSharp/IO/EndianBinaryReader.cs +++ b/src/ImageSharp/IO/EndianBinaryReader.cs @@ -42,17 +42,23 @@ namespace ImageSharp.IO private bool disposed; /// - /// Equivalent of System.IO.BinaryWriter, but with either endianness, depending on + /// Initializes a new instance of the class. + /// Equivalent of , but with either endianness, depending on /// the EndianBitConverter it is constructed with. /// - /// Converter to use when reading data - /// Stream to read data from + /// + /// Converter to use when reading data + /// + /// + /// Stream to read data from + /// public EndianBinaryReader(EndianBitConverter bitConverter, Stream stream) : this(bitConverter, stream, Encoding.UTF8) { } /// + /// Initializes a new instance of the class. /// Constructs a new binary reader with the given bit converter, reading /// to the given stream, using the given encoding. /// diff --git a/src/ImageSharp/Image/ImageProcessingExtensions.cs b/src/ImageSharp/Image/ImageProcessingExtensions.cs index 7ebaf8f15..69c283f9f 100644 --- a/src/ImageSharp/Image/ImageProcessingExtensions.cs +++ b/src/ImageSharp/Image/ImageProcessingExtensions.cs @@ -48,88 +48,6 @@ namespace ImageSharp return PerformAction(source, (sourceImage) => processor.Apply(sourceImage, sourceRectangle)); } - /// - /// Applies the processor to the image. - /// This method does not resize the target image. - /// - /// The pixel format. - /// The packed format. uint, long, float. - /// The image this method extends. - /// The processor to apply to the image. - /// The . - internal static Image Process(this Image source, IImageSamplingProcessor processor) - where TColor : struct, IPackedPixel - where TPacked : struct - { - return Process(source, source.Bounds, processor); - } - - /// - /// Applies the processor to the image. - /// This method does not resize the target image. - /// - /// The pixel format. - /// The packed format. uint, long, float. - /// The image this method extends. - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// The processors to apply to the image. - /// The . - internal static Image Process(this Image source, Rectangle sourceRectangle, IImageSamplingProcessor processor) - where TColor : struct, IPackedPixel - where TPacked : struct - { - return PerformAction(source, true, (sourceImage, targetImage) => processor.Apply(targetImage, sourceImage, sourceRectangle)); - } - - /// - /// Applies the processor to the image. - /// - /// This method resizes the image. - /// - /// - /// The pixel format. - /// The packed format. long, float. - /// The source image. Cannot be null. - /// The target image width. - /// The target image height. - /// The processor to apply to the image. - /// The . - internal static Image Process(this Image source, int width, int height, IImageSamplingProcessor sampler) - where TColor : struct, IPackedPixel - where TPacked : struct - { - return Process(source, width, height, source.Bounds, default(Rectangle), sampler); - } - - /// - /// Applies the processor to the image. - /// - /// This method does will resize the target image if the source and target rectangles are different. - /// - /// - /// The pixel format. - /// The packed format. long, float. - /// The source image. Cannot be null. - /// The target image width. - /// The target image height. - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// The processor to apply to the image. - /// The . - internal static Image Process(this Image source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSamplingProcessor sampler) - where TColor : struct, IPackedPixel - where TPacked : struct - { - return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle)); - } - /// /// Performs the given action on the source image. /// @@ -151,53 +69,5 @@ namespace ImageSharp return source; } - - /// - /// Performs the given action on the source image. - /// - /// The pixel format. - /// The packed format. long, float. - /// The image to perform the action against. - /// Whether to clone the image. - /// The to perform against the image. - /// The . - private static Image PerformAction(Image source, bool clone, Action, ImageBase> action) - where TColor : struct, IPackedPixel - where TPacked : struct - { - Image transformedImage = clone - ? new Image(source) - : new Image(); - - // Several properties still require copying - if (!clone) - { - transformedImage.CopyProperties(source); - } - - action(source, transformedImage); - - for (int i = 0; i < source.Frames.Count; i++) - { - ImageFrame sourceFrame = source.Frames[i]; - ImageFrame tranformedFrame = clone - ? new ImageFrame(sourceFrame) - : new ImageFrame { FrameDelay = sourceFrame.FrameDelay }; - - action(sourceFrame, tranformedFrame); - - if (!clone) - { - transformedImage.Frames.Add(tranformedFrame); - } - else - { - transformedImage.Frames[i] = tranformedFrame; - } - } - - source = transformedImage; - return source; - } } } diff --git a/src/ImageSharp/Samplers/Processors/IImageSamplingProcessor.cs b/src/ImageSharp/Samplers/Processors/IImageSamplingProcessor.cs deleted file mode 100644 index 756c96612..000000000 --- a/src/ImageSharp/Samplers/Processors/IImageSamplingProcessor.cs +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Processors -{ - /// - /// Encapsulates methods to alter the pixels of an image. The processor creates a copy of the original image to operate on. - /// - /// The pixel format. - /// The packed format. uint, long, float. - public interface IImageSamplingProcessor : IImageProcessor - where TColor : struct, IPackedPixel - where TPacked : struct - { - /// - /// Applies the process to the specified portion of the specified . - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// - /// The method keeps the source image unchanged and returns the - /// the result of image processing filter as new image. - /// - /// - /// is null or is null. - /// - /// - /// doesnt fit the dimension of the image. - /// - void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle); - - /// - /// Applies the process to the specified portion of the specified at the specified - /// location and with the specified size. - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// The target width. - /// The target height. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// - /// The method keeps the source image unchanged and returns the - /// the result of image process as new image. - /// - void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle); - } -} diff --git a/src/ImageSharp/Samplers/Processors/ImageSamplingProcessor.cs b/src/ImageSharp/Samplers/Processors/ImageSamplingProcessor.cs deleted file mode 100644 index aa9d583a4..000000000 --- a/src/ImageSharp/Samplers/Processors/ImageSamplingProcessor.cs +++ /dev/null @@ -1,119 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Processors -{ - using System; - - /// - /// Encapsulates methods to alter the pixels of an image. The processor creates a copy of the original image to operate on. - /// - /// The pixel format. - /// The packed format. uint, long, float. - public abstract class ImageSamplingProcessor : ImageProcessor, IImageSamplingProcessor - where TColor : struct, IPackedPixel - where TPacked : struct - { - /// - public void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle) - { - try - { - this.OnApply(target, source, target.Bounds, sourceRectangle); - - this.Apply(target, source, target.Bounds, sourceRectangle, sourceRectangle.Y, sourceRectangle.Bottom); - - this.AfterApply(target, source, target.Bounds, sourceRectangle); - } - catch (Exception ex) - { - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex); - } - } - - /// - public void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle)) - { - try - { - TColor[] pixels = new TColor[width * height]; - target.SetPixels(width, height, pixels); - - // Ensure we always have bounds. - if (sourceRectangle == Rectangle.Empty) - { - sourceRectangle = source.Bounds; - } - - if (targetRectangle == Rectangle.Empty) - { - targetRectangle = target.Bounds; - } - - this.OnApply(target, source, targetRectangle, sourceRectangle); - - this.Apply(target, source, targetRectangle, sourceRectangle, targetRectangle.Y, targetRectangle.Bottom); - - this.AfterApply(target, source, target.Bounds, sourceRectangle); - } - catch (Exception ex) - { - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex); - } - } - - /// - /// Applies the process to the specified portion of the specified at the specified location - /// and with the specified size. - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// The index of the row within the source image to start processing. - /// The index of the row within the source image to end processing. - /// - /// The method keeps the source image unchanged and returns the the result of image process as new image. - /// - public abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY); - - /// - /// This method is called before the process is applied to prepare the processor. - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - protected virtual void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - } - - /// - /// This method is called after the process is applied to prepare the processor. - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - protected virtual void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs b/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs index 75e2020cd..69c24ab3b 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // diff --git a/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs index e6fa22a6f..e69de29bb 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs @@ -1,66 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System; - using System.IO; - - using Xunit; - - public class OilPaintTest : FileTestBase - { - public static readonly TheoryData> OilPaintValues - = new TheoryData> - { - new Tuple(15, 10), - new Tuple(8, 5) - }; - - [Theory] - [MemberData(nameof(OilPaintValues))] - public void ImageShouldApplyOilPaintFilter(Tuple value) - { - string path = CreateOutputDirectory("OilPaint"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - Image image = file.CreateImage(); - - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - if (value.Item2 < image.Width && value.Item2 < image.Height) - { - image.OilPaint(value.Item1, value.Item2) - .Save(output); - } - } - } - } - - [Theory] - [MemberData(nameof(OilPaintValues))] - public void ImageShouldApplyOilPaintFilterInBox(Tuple value) - { - string path = CreateOutputDirectory("OilPaint"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - Image image = file.CreateImage(); - - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - if (value.Item2 < image.Width && value.Item2 < image.Height) - { - image.OilPaint(value.Item1, value.Item2, new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2)) - .Save(output); - } - } - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs b/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs index 8655dfb96..e69de29bb 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs @@ -1,59 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.IO; - - using Xunit; - - public class PixelateTest : FileTestBase - { - public static readonly TheoryData PixelateValues - = new TheoryData - { - 4 , - 8 - }; - - [Theory] - [MemberData(nameof(PixelateValues))] - public void ImageShouldApplyPixelateFilter(int value) - { - string path = CreateOutputDirectory("Pixelate"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value); - Image image = file.CreateImage(); - - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Pixelate(value) - .Save(output); - } - } - } - - [Theory] - [MemberData(nameof(PixelateValues))] - public void ImageShouldApplyPixelateFilterInBox(int value) - { - string path = CreateOutputDirectory("Pixelate"); - - foreach (TestFile file in Files) - { - string filename = file.GetFileName(value + "-InBox"); - Image image = file.CreateImage(); - - using (FileStream output = File.OpenWrite($"{path}/{filename}")) - { - image.Pixelate(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)) - .Save(output); - } - } - } - } -} \ No newline at end of file