diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index 2cdf7b750..af3cae8eb 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -196,6 +196,7 @@
+
diff --git a/src/ImageProcessor/Samplers/Resize - Copy.cs b/src/ImageProcessor/Samplers/Resize - Copy.cs
new file mode 100644
index 000000000..65a07933f
--- /dev/null
+++ b/src/ImageProcessor/Samplers/Resize - Copy.cs
@@ -0,0 +1,180 @@
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessor.Samplers
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Provides methods that allow the resizing of images using various resampling algorithms.
+ ///
+ public class Resize : ParallelImageProcessor
+ {
+ ///
+ /// The epsilon for comparing floating point numbers.
+ ///
+ private const float Epsilon = 0.0001f;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The sampler to perform the resize operation.
+ ///
+ public Resize(IResampler sampler)
+ {
+ Guard.NotNull(sampler, nameof(sampler));
+
+ this.Sampler = sampler;
+ }
+
+ ///
+ /// Gets the sampler to perform the resize operation.
+ ///
+ public IResampler Sampler { get; }
+
+ ///
+ protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
+ {
+ int sourceWidth = source.Width;
+ int sourceHeight = source.Height;
+
+ int width = target.Width;
+ int height = target.Height;
+
+ int targetY = targetRectangle.Y;
+ int startX = targetRectangle.X;
+ int endX = targetRectangle.Right;
+
+ // Scaling factors
+ double widthFactor = sourceWidth / (double)targetRectangle.Width;
+ double heightFactor = sourceHeight / (double)targetRectangle.Height;
+ int sectionHeight = endY - startY;
+
+ Weights[] horizontalWeights = this.PrecomputeWeights(targetRectangle.Width, sourceRectangle.Width, this.Sampler);
+ Weights[] verticalWeights = this.PrecomputeWeights(sectionHeight, (int)((sectionHeight * heightFactor) + .5), this.Sampler);
+
+ // Width and height decreased by 1
+ int maxHeight = sourceHeight - 1;
+ int maxWidth = sourceWidth - 1;
+
+ for (int y = startY; y < endY; y++)
+ {
+ List verticalValues = verticalWeights[y - startY].Values;
+ double verticalSum = verticalWeights[y - startY].Sum;
+
+ for (int x = startX; x < endX; x++)
+ {
+ List horizontalValues = horizontalWeights[x - startX].Values;
+ double horizontalSum = horizontalWeights[x - startX].Sum;
+
+
+ // Destination color components
+ double r = 0;
+ double g = 0;
+ double b = 0;
+ double a = 0;
+
+ foreach (Weight yw in verticalValues)
+ {
+ int originY = yw.Index + startY; //- targetY;//(int)(((y - targetY) * heightFactor) - 0.5);
+ originY = originY.Clamp(0, maxHeight);
+
+ foreach (Weight xw in horizontalValues)
+ {
+ int originX = xw.Index;//(int)(((x - startX) * widthFactor) - 0.5);
+ originX = originX.Clamp(0, maxWidth);
+
+ Bgra sourceColor = source[originX, originY];
+ r += sourceColor.R * (yw.Value / verticalSum) * (xw.Value / horizontalSum);
+ g += sourceColor.G * (yw.Value / verticalSum) * (xw.Value / horizontalSum);
+ b += sourceColor.B * (yw.Value / verticalSum) * (xw.Value / horizontalSum);
+ a += sourceColor.A * (yw.Value / verticalSum) * (xw.Value / horizontalSum);
+ }
+ }
+
+ Bgra destinationColor = new Bgra(b.ToByte(), g.ToByte(), r.ToByte(), a.ToByte());
+ target[x, y] = destinationColor;
+ }
+ }
+ }
+
+ private Weights[] PrecomputeWeights(int dstSize, int srcSize, IResampler sampler)
+ {
+ float du = srcSize / (float)dstSize;
+ float scale = du;
+
+ if (scale < 1)
+ {
+ scale = 1;
+ }
+
+ double ru = Math.Ceiling(scale * sampler.Radius);
+ Weights[] result = new Weights[dstSize];
+
+ for (int i = 0; i < dstSize; i++)
+ {
+ double fu = ((i + .5) * du) - 0.5;
+ int startU = (int)Math.Ceiling(fu - ru);
+
+ if (startU < 0)
+ {
+ startU = 0;
+ }
+
+ int endU = (int)Math.Floor(fu + ru);
+
+ if (endU > srcSize - 1)
+ {
+ endU = srcSize - 1;
+ }
+
+ double sum = 0;
+ result[i] = new Weights();
+
+ for (int a = startU; a <= endU; a++)
+ {
+ double w = 255 * sampler.GetValue((a - fu) / scale);
+
+ if (Math.Abs(w) > Epsilon)
+ {
+ sum += w;
+ result[i].Values.Add(new Weight(a, w));
+ }
+ }
+
+ result[i].Sum = sum;
+ }
+
+ return result;
+ }
+
+ public struct Weight
+ {
+ public Weight(int index, double value)
+ {
+ this.Index = index;
+ this.Value = value;
+ }
+
+ public readonly int Index;
+
+ public readonly double Value;
+ }
+
+ public class Weights
+ {
+ public Weights()
+ {
+ this.Values = new List();
+ }
+
+ public List Values { get; set; }
+
+ public double Sum { get; set; }
+ }
+ }
+}
diff --git a/src/ImageProcessor/Samplers/Resize.cs b/src/ImageProcessor/Samplers/Resize.cs
index ce146186b..47125cfd3 100644
--- a/src/ImageProcessor/Samplers/Resize.cs
+++ b/src/ImageProcessor/Samplers/Resize.cs
@@ -10,7 +10,7 @@ namespace ImageProcessor.Samplers
///
/// Provides methods that allow the resizing of images using various resampling algorithms.
///
- public class Resize : ParallelImageProcessor
+ public class ResizeB : ParallelImageProcessor
{
///
/// The epsilon for comparing floating point numbers.
@@ -23,7 +23,7 @@ namespace ImageProcessor.Samplers
///
/// The sampler to perform the resize operation.
///
- public Resize(IResampler sampler)
+ public ResizeB(IResampler sampler)
{
Guard.NotNull(sampler, nameof(sampler));
diff --git a/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs b/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
index 1804557fa..da88b7c94 100644
--- a/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
+++ b/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
@@ -19,8 +19,8 @@ namespace ImageProcessor.Tests
///
public static readonly List Files = new List
{
- "../../TestImages/Formats/Jpg/Backdrop.jpg",
- "../../TestImages/Formats/Jpg/Calliphora.jpg",
+ //"../../TestImages/Formats/Jpg/Backdrop.jpg",
+ //"../../TestImages/Formats/Jpg/Calliphora.jpg",
//"../../TestImages/Formats/Bmp/Car.bmp",
//"../../TestImages/Formats/Png/cmyk.png",
//"../../TestImages/Formats/Gif/leaf.gif"
diff --git a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
index 9b15f8013..759095b33 100644
--- a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
+++ b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
@@ -13,18 +13,18 @@ namespace ImageProcessor.Tests
public static readonly TheoryData Samplers =
new TheoryData
{
- { "Bicubic", new BicubicResampler() },
- { "Bilinear", new TriangleResampler() },
+ //{ "Bicubic", new BicubicResampler() },
+ //{ "Bilinear", new TriangleResampler() },
{ "NearestNeighbour", new BoxResampler() },
- { "Lanczos3", new Lanczos3Resampler() },
+ //{ "Lanczos3", new Lanczos3Resampler() },
{ "Lanczos8", new Lanczos8Resampler() },
- { "MitchellNetravali", new MitchellNetravaliResampler() },
- { "Hermite", new HermiteResampler() },
- { "Spline", new SplineResampler() },
- { "Robidoux", new RobidouxResampler() },
- { "RobidouxSharp", new RobidouxSharpResampler() },
- { "RobidouxSoft", new RobidouxSoftResampler() },
- { "Welch", new WelchResampler() }
+ //{ "MitchellNetravali", new MitchellNetravaliResampler() },
+ //{ "Hermite", new HermiteResampler() },
+ //{ "Spline", new SplineResampler() },
+ //{ "Robidoux", new RobidouxResampler() },
+ //{ "RobidouxSharp", new RobidouxSharpResampler() },
+ //{ "RobidouxSoft", new RobidouxSoftResampler() },
+ //{ "Welch", new WelchResampler() }
};
[Theory]
@@ -45,7 +45,7 @@ namespace ImageProcessor.Tests
string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file);
using (FileStream output = File.OpenWrite($"Resized/{filename}"))
{
- image.Resize(100, 100, sampler).Save(output);
+ image.Resize(500, 500, sampler).Save(output);
}
Trace.WriteLine($"{name}: {watch.ElapsedMilliseconds}ms");