diff --git a/src/ImageProcessorCore/Samplers/ImageSamplerExtensions.cs b/src/ImageProcessorCore/Samplers/ImageSamplerExtensions.cs
index 542050ecd2..d741ccfd30 100644
--- a/src/ImageProcessorCore/Samplers/ImageSamplerExtensions.cs
+++ b/src/ImageProcessorCore/Samplers/ImageSamplerExtensions.cs
@@ -176,34 +176,7 @@ namespace ImageProcessorCore.Samplers
/// The
public static Image Rotate(this Image source, float degrees, ProgressEventHandler progressHandler = null)
{
- return Rotate(source, degrees, new BicubicResampler(), false, progressHandler);
- }
-
- ///
- /// Rotates an image by the given angle in degrees.
- ///
- /// The image to resize.
- /// The angle in degrees to perform the rotation.
- /// Whether to compress and expand the image color-space to gamma correct the image during processing.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Rotate(this Image source, float degrees, bool compand, ProgressEventHandler progressHandler = null)
- {
- return Rotate(source, degrees, new BicubicResampler(), compand, progressHandler);
- }
-
- ///
- /// Rotates an image by the given angle in degrees.
- ///
- /// The image to resize.
- /// The angle in degrees to perform the rotation.
- /// The to perform the resampling.
- /// Whether to compress and expand the image color-space to gamma correct the image during processing.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Rotate(this Image source, float degrees, IResampler sampler, bool compand, ProgressEventHandler progressHandler = null)
- {
- Rotate processor = new Rotate(sampler) { Angle = degrees, Compand = compand };
+ Rotate processor = new Rotate { Angle = degrees };
processor.OnProgress += progressHandler;
try
diff --git a/src/ImageProcessorCore/Samplers/Resampler.cs b/src/ImageProcessorCore/Samplers/Resampler.cs
index 0554b18e0d..368e031939 100644
--- a/src/ImageProcessorCore/Samplers/Resampler.cs
+++ b/src/ImageProcessorCore/Samplers/Resampler.cs
@@ -6,8 +6,6 @@
namespace ImageProcessorCore.Samplers
{
using System;
- using System.Collections.Generic;
- using System.Threading.Tasks;
///
/// Provides methods that allow the resampling of images using various algorithms.
@@ -54,58 +52,57 @@ namespace ImageProcessorCore.Samplers
///
protected Weights[] PrecomputeWeights(int destinationSize, int sourceSize)
{
- float xscale = destinationSize / (float)sourceSize;
- float width;
+ float scale = (float)destinationSize / sourceSize;
IResampler sampler = this.Sampler;
- float fwidth = sampler.Radius;
- float fscale;
+ float radius = sampler.Radius;
double left;
double right;
- double weight = 0;
- int n = 0;
- int k;
+ double weight;
+ int index;
+ int sum;
Weights[] result = new Weights[destinationSize];
- // When expanding, broaden the effective kernel support so that we still
+ // When shrinking, broaden the effective kernel support so that we still
// visit every source pixel.
- if (xscale < 0)
+ if (scale < 1)
{
- width = sampler.Radius / xscale;
- fscale = 1 / xscale;
+ float width = radius / scale;
+ float filterScale = 1 / scale;
// Make the weights slices, one source for each column or row.
for (int i = 0; i < destinationSize; i++)
{
- float centre = i / xscale;
+ float centre = i / scale;
left = Math.Ceiling(centre - width);
right = Math.Floor(centre + width);
- float sum = 0;
- result[i] = new Weights();
- List builder = new List();
+
+ result[i] = new Weights
+ {
+ Sum = 0,
+ Values = new Weight[(int)Math.Floor(2 * width + 1)]
+ };
+
for (double j = left; j <= right; j++)
{
weight = centre - j;
- weight = sampler.GetValue((float)weight / fscale) / fscale;
+ weight = sampler.GetValue((float)(weight / filterScale)) / filterScale;
if (j < 0)
{
- n = (int)-j;
+ index = (int)-j;
}
else if (j >= sourceSize)
{
- n = (int)((sourceSize - j) + sourceSize - 1);
+ index = (int)((sourceSize - j) + sourceSize - 1);
}
else
{
- n = (int)j;
+ index = (int)j;
}
- sum++;
- builder.Add(new Weight(n, (float)weight));
+ sum = (int)result[i].Sum++;
+ result[i].Values[sum] = new Weight(index, (float)weight);
}
-
- result[i].Values = builder.ToArray();
- result[i].Sum = sum;
}
}
else
@@ -113,122 +110,46 @@ namespace ImageProcessorCore.Samplers
// Make the weights slices, one source for each column or row.
for (int i = 0; i < destinationSize; i++)
{
- float centre = i / xscale;
- left = Math.Ceiling(centre - fwidth);
- right = Math.Floor(centre + fwidth);
- float sum = 0;
- result[i] = new Weights();
+ float centre = i / scale;
+ left = Math.Ceiling(centre - radius);
+ right = Math.Floor(centre + radius);
+ result[i] = new Weights
+ {
+ Sum = 0,
+ Values = new Weight[(int)(radius * 2 + 1)]
+ };
- List builder = new List();
for (double j = left; j <= right; j++)
{
weight = centre - j;
weight = sampler.GetValue((float)weight);
if (j < 0)
{
- n = (int)-j;
+ index = (int)-j;
}
else if (j >= sourceSize)
{
- n = (int)((sourceSize - j) + sourceSize - 1);
+ index = (int)((sourceSize - j) + sourceSize - 1);
}
else
{
- n = (int)j;
+ index = (int)j;
}
- sum++;
- builder.Add(new Weight(n, (float)weight));
+ sum = (int)result[i].Sum++;
+ result[i].Values[sum] = new Weight(index, (float)weight);
}
-
- result[i].Values = builder.ToArray();
- result[i].Sum = sum;
}
}
return result;
}
- //protected Weights[] PrecomputeWeights(int destinationSize, int sourceSize)
- //{
- // IResampler sampler = this.Sampler;
- // float ratio = sourceSize / (float)destinationSize;
- // float scale = ratio;
-
- // // When shrinking, broaden the effective kernel support so that we still
- // // visit every source pixel.
- // if (scale < 1)
- // {
- // scale = 1;
- // }
-
- // float scaledRadius = (float)Math.Ceiling(scale * sampler.Radius);
- // Weights[] result = new Weights[destinationSize];
-
- // // Make the weights slices, one source for each column or row.
- // Parallel.For(
- // 0,
- // destinationSize,
- // i =>
- // {
- // float center = ((i + .5f) * ratio) - 0.5f;
- // int start = (int)Math.Ceiling(center - scaledRadius);
-
- // if (start < 0)
- // {
- // start = 0;
- // }
-
- // int end = (int)Math.Floor(center + scaledRadius);
-
- // if (end > sourceSize)
- // {
- // end = sourceSize;
-
- // if (end < start)
- // {
- // end = start;
- // }
- // }
-
- // float sum = 0;
- // result[i] = new Weights();
-
- // List builder = new List();
- // for (int a = start; a < end; a++)
- // {
- // float w = sampler.GetValue((a - center) / scale);
-
- // if (w < 0 || w > 0)
- // {
- // sum += w;
- // builder.Add(new Weight(a, w));
- // }
- // }
-
- // // Normalise the values
- // if (sum > 0 || sum < 0)
- // {
- // builder.ForEach(w => w.Value /= sum);
- // }
-
- // result[i].Values = builder.ToArray();
- // result[i].Sum = sum;
- // });
-
- // return result;
- //}
-
///
/// Represents the weight to be added to a scaled pixel.
///
- protected class Weight
+ protected struct Weight
{
- ///
- /// The pixel index.
- ///
- public readonly int Index;
-
///
/// Initializes a new instance of the class.
///
@@ -241,9 +162,14 @@ namespace ImageProcessorCore.Samplers
}
///
- /// Gets or sets the result of the interpolation algorithm.
+ /// Gets the pixel index.
+ ///
+ public int Index { get; }
+
+ ///
+ /// Gets the result of the interpolation algorithm.
///
- public float Value { get; set; }
+ public float Value { get; }
}
///
@@ -262,4 +188,4 @@ namespace ImageProcessorCore.Samplers
public float Sum { get; set; }
}
}
-}
+}
\ No newline at end of file
diff --git a/src/ImageProcessorCore/Samplers/Resamplers/BoxResampler.cs b/src/ImageProcessorCore/Samplers/Resamplers/BoxResampler.cs
index 6ef5c0e351..82c405114b 100644
--- a/src/ImageProcessorCore/Samplers/Resamplers/BoxResampler.cs
+++ b/src/ImageProcessorCore/Samplers/Resamplers/BoxResampler.cs
@@ -17,12 +17,7 @@ namespace ImageProcessorCore.Samplers
///
public float GetValue(float x)
{
- if (x < 0)
- {
- x = -x;
- }
-
- if (x <= 0.5)
+ if (x > -0.5 && x <= 0.5)
{
return 1;
}
diff --git a/src/ImageProcessorCore/Samplers/Rotate.cs b/src/ImageProcessorCore/Samplers/Rotate.cs
index 77cc8e7e7e..42032ae2a7 100644
--- a/src/ImageProcessorCore/Samplers/Rotate.cs
+++ b/src/ImageProcessorCore/Samplers/Rotate.cs
@@ -10,24 +10,13 @@ namespace ImageProcessorCore.Samplers
///
/// Provides methods that allow the rotating of images using various algorithms.
///
- public class Rotate : Resampler
+ public class Rotate : ImageSampler
{
///
/// The angle of rotation.
///
private float angle;
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The sampler to perform the resize operation.
- ///
- public Rotate(IResampler sampler)
- : base(sampler)
- {
- }
-
///
/// Gets or sets the angle of rotation.
///
@@ -54,16 +43,6 @@ namespace ImageProcessorCore.Samplers
}
}
- ///
- protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, 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 Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
@@ -73,45 +52,11 @@ namespace ImageProcessorCore.Samplers
int endX = targetRectangle.Right;
float negativeAngle = -this.angle;
Point centre = Rectangle.Center(sourceRectangle);
- bool compand = this.Compand;
-
- if (this.Sampler is NearestNeighborResampler)
- {
- // Scaling factors
- float widthFactor = source.Width / (float)target.Width;
- float heightFactor = source.Height / (float)target.Height;
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= targetY && y < targetBottom)
- {
- // Y coordinates of source points
- int originY = (int)((y - targetY) * heightFactor);
+ // Scaling factors
+ float widthFactor = source.Width / (float)target.Width;
+ float heightFactor = source.Height / (float)target.Height;
- for (int x = startX; x < endX; x++)
- {
- // X coordinates of source points
- int originX = (int)((x - startX) * widthFactor);
-
- // Rotate at the centre point
- Point rotated = Point.Rotate(new Point(originX, originY), centre, negativeAngle);
- if (sourceRectangle.Contains(rotated.X, rotated.Y))
- {
- target[x, y] = source[rotated.X, rotated.Y];
- }
- }
- this.OnRowProcessed();
- }
- });
-
- // Break out now.
- return;
- }
-
- // Interpolate the image using the calculated weights.
Parallel.For(
startY,
endY,
@@ -119,46 +64,21 @@ namespace ImageProcessorCore.Samplers
{
if (y >= targetY && y < targetBottom)
{
- Weight[] verticalValues = this.VerticalWeights[y].Values;
+ // Y coordinates of source points
+ int originY = (int)((y - targetY) * heightFactor);
for (int x = startX; x < endX; x++)
{
- Weight[] horizontalValues = this.HorizontalWeights[x].Values;
+ // X coordinates of source points
+ int originX = (int)((x - startX) * widthFactor);
- // Destination color components
- Color destination = new Color();
-
- foreach (Weight yw in verticalValues)
+ // Rotate at the centre point
+ Point rotated = Point.Rotate(new Point(originX, originY), centre, negativeAngle);
+ if (sourceRectangle.Contains(rotated.X, rotated.Y))
{
- int originY = yw.Index;
-
- foreach (Weight xw in horizontalValues)
- {
- int originX = xw.Index;
-
- // Rotate at the centre point
- Point rotated = Point.Rotate(new Point(originX, originY), centre, negativeAngle);
- if (sourceRectangle.Contains(rotated.X, rotated.Y))
- {
- target[x, y] = source[rotated.X, rotated.Y];
- }
-
- if (sourceRectangle.Contains(rotated.X, rotated.Y))
- {
- Color sourceColor = compand ? Color.Expand(source[rotated.X, rotated.Y]) : source[rotated.X, rotated.Y];
- destination += sourceColor * yw.Value * xw.Value;
- }
- }
+ target[x, y] = source[rotated.X, rotated.Y];
}
-
- if (compand)
- {
- destination = Color.Compress(destination);
- }
-
- target[x, y] = destination;
}
-
this.OnRowProcessed();
}
});