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
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/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 98%
rename from src/ImageSharp/Samplers/Convolution/DetectEdges.cs
rename to src/ImageSharp/Filters/Convolution/DetectEdges.cs
index 649e0cf64..3ddcc6672 100644
--- a/src/ImageSharp/Samplers/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/Samplers/Convolution/GuassianBlur.cs b/src/ImageSharp/Filters/Convolution/GaussianBlur.cs
similarity index 81%
rename from src/ImageSharp/Samplers/Convolution/GuassianBlur.cs
rename to src/ImageSharp/Filters/Convolution/GaussianBlur.cs
index ef09a18f5..9bc814c5c 100644
--- a/src/ImageSharp/Samplers/Convolution/GuassianBlur.cs
+++ b/src/ImageSharp/Filters/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/Filters/Convolution/GaussianSharpen.cs
similarity index 80%
rename from src/ImageSharp/Samplers/Convolution/GuassianSharpen.cs
rename to src/ImageSharp/Filters/Convolution/GaussianSharpen.cs
index 6b433f6ae..b3b5efa3f 100644
--- a/src/ImageSharp/Samplers/Convolution/GuassianSharpen.cs
+++ b/src/ImageSharp/Filters/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/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/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/Filters/Effects/Pixelate.cs b/src/ImageSharp/Filters/Effects/Pixelate.cs
new file mode 100644
index 000000000..e69de29bb
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..afebcd8ed 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,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,
@@ -116,14 +117,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/IEdgeDetectorProcessor.cs
similarity index 94%
rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs
rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs
index ac1c5a6fa..65abc525f 100644
--- a/src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorSampler.cs
+++ b/src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.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 94%
rename from src/ImageSharp/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
rename to src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
index 5fbf54b30..039836230 100644
--- a/src/ImageSharp/Samplers/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/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/GuassianBlurProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs
similarity index 84%
rename from src/ImageSharp/Samplers/Processors/Convolution/GuassianBlurProcessor.cs
rename to src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs
index e6af445b4..8553e4264 100644
--- a/src/ImageSharp/Samplers/Processors/Convolution/GuassianBlurProcessor.cs
+++ b/src/ImageSharp/Filters/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 : ImageFilteringProcessor
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;
@@ -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/GuassianSharpenProcessor.cs b/src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs
similarity index 87%
rename from src/ImageSharp/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs
rename to src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs
index 56cf94ea3..48790a733 100644
--- a/src/ImageSharp/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs
+++ b/src/ImageSharp/Filters/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 : ImageFilteringProcessor
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;
@@ -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/Samplers/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs
similarity index 90%
rename from src/ImageSharp/Samplers/Processors/Effects/OilPaintingProcessor.cs
rename to src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs
index 77b7a158f..cddf74af6 100644
--- a/src/ImageSharp/Samplers/Processors/Effects/OilPaintingProcessor.cs
+++ b/src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs
@@ -10,17 +10,17 @@ 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.
/// 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/src/ImageSharp/Samplers/Processors/Effects/PixelateProcesso.cs b/src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs
similarity index 84%
rename from src/ImageSharp/Samplers/Processors/Effects/PixelateProcesso.cs
rename to src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs
index 41775ed97..17b0450e0 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.
//
@@ -10,22 +10,22 @@ 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.
- 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/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/CropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs
new file mode 100644
index 000000000..1e7916d06
--- /dev/null
+++ b/src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs
@@ -0,0 +1,68 @@
+//
+// 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.
+ ///
+ /// 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 cropped rectangle.
+ public CropProcessor(Rectangle cropRectangle)
+ {
+ this.CropRectangle = cropRectangle;
+ }
+
+ ///
+ /// Gets the width.
+ ///
+ public Rectangle CropRectangle { get; }
+
+ ///
+ protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY)
+ {
+ if (this.CropRectangle == sourceRectangle)
+ {
+ return;
+ }
+
+ 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.CropRectangle.Width * this.CropRectangle.Height];
+
+ using (PixelAccessor sourcePixels = source.Lock())
+ using (PixelAccessor targetPixels = target.Lock(this.CropRectangle.Width, this.CropRectangle.Height))
+ {
+ Parallel.For(
+ minY,
+ maxY,
+ this.ParallelOptions,
+ y =>
+ {
+ for (int x = minX; x < maxX; x++)
+ {
+ targetPixels[x - minX, y - minY] = sourcePixels[x, y];
+ }
+ });
+ }
+
+ source.SetPixels(this.CropRectangle.Width, this.CropRectangle.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
new file mode 100644
index 000000000..263c63790
--- /dev/null
+++ b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs
@@ -0,0 +1,59 @@
+//
+// 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);
+ temp.ClonePixels(source.Width, source.Height, source.Pixels);
+
+ // Detect the edges.
+ new SobelProcessor().Apply(temp, 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/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 63%
rename from src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs
rename to src/ImageSharp/Filters/Processors/Transforms/Matrix3x2Processor.cs
index 169441648..e72e8aa61 100644
--- a/src/ImageSharp/Samplers/Processors/Transforms/Matrix3x2Processor.cs
+++ b/src/ImageSharp/Filters/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/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/Samplers/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs
similarity index 73%
rename from src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs
rename to src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs
index a9e69678d..2ab16d592 100644
--- a/src/ImageSharp/Samplers/Processors/Transforms/RotateProcessor.cs
+++ b/src/ImageSharp/Filters/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