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
};