Browse Source

ResizeWindow refactor 3

pull/888/head
Anton Firszov 8 years ago
parent
commit
545abf2d06
  1. 11
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs
  2. 5
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs
  3. 12
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs
  4. 433
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs

11
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs

@ -54,11 +54,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
this.radius = radius; this.radius = radius;
this.sourceLength = sourceLength; this.sourceLength = sourceLength;
this.DestinationLength = destinationLength; this.DestinationLength = destinationLength;
int maxWidth = (radius * 2) + 1; this.MaxDiameter = (radius * 2) + 1;
this.data = memoryAllocator.Allocate2D<float>(maxWidth, bufferHeight, AllocationOptions.Clean); this.data = memoryAllocator.Allocate2D<float>(this.MaxDiameter, bufferHeight, AllocationOptions.Clean);
this.pinHandle = this.data.Memory.Pin(); this.pinHandle = this.data.Memory.Pin();
this.kernels = new ResizeKernel[destinationLength]; this.kernels = new ResizeKernel[destinationLength];
this.tempValues = new double[maxWidth]; this.tempValues = new double[this.MaxDiameter];
} }
/// <summary> /// <summary>
@ -66,6 +66,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// </summary> /// </summary>
public int DestinationLength { get; } public int DestinationLength { get; }
/// <summary>
/// Gets the maximum diameter of the kernels.
/// </summary>
public int MaxDiameter { get; }
/// <summary> /// <summary>
/// Gets a string of information to help debugging /// Gets a string of information to help debugging
/// </summary> /// </summary>

5
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs

@ -262,6 +262,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Ensure offsets are normalized for cropping and padding. // Ensure offsets are normalized for cropping and padding.
ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY); ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY);
if (kernel.Left + kernel.Length > resizeWindow.Bottom)
{
resizeWindow.Slide();
}
ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempColSpan); ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempColSpan);
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)

12
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs

@ -13,7 +13,7 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{ {
class ResizeWindow<TPixel> : IDisposable internal class ResizeWindow<TPixel> : IDisposable
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private readonly Buffer2D<Vector4> buffer; private readonly Buffer2D<Vector4> buffer;
@ -36,6 +36,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly Rectangle workingRectangle; private readonly Rectangle workingRectangle;
private readonly int diameter;
public ResizeWindow( public ResizeWindow(
Configuration configuration, Configuration configuration,
BufferArea<TPixel> source, BufferArea<TPixel> source,
@ -54,6 +56,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
this.verticalKernelMap = verticalKernelMap; this.verticalKernelMap = verticalKernelMap;
this.workingRectangle = workingRectangle; this.workingRectangle = workingRectangle;
this.startX = startX; this.startX = startX;
this.diameter = verticalKernelMap.MaxDiameter;
this.buffer = configuration.MemoryAllocator.Allocate2D<Vector4>( this.buffer = configuration.MemoryAllocator.Allocate2D<Vector4>(
this.sourceRectangle.Height, this.sourceRectangle.Height,
destWidth, destWidth,
@ -102,5 +107,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
} }
} }
} }
public void Slide()
{
throw new InvalidOperationException("Shouldn't happen yet!");
}
} }
} }

433
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs

@ -5,38 +5,92 @@ using System;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Primitives;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives; using SixLabors.Primitives;
using Xunit; using Xunit;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{ {
public class ResizeTests public class ResizeTests
{ {
public static readonly string[] CommonTestImages = { TestImages.Png.CalliphoraPartial }; private const PixelTypes CommonNonDefaultPixelTypes =
PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector;
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.07F); private const PixelTypes DefaultPixelType = PixelTypes.Rgba32;
public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames(); public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames();
public static readonly string[] CommonTestImages = { TestImages.Png.CalliphoraPartial };
public static readonly string[] SmokeTestResamplerNames = public static readonly string[] SmokeTestResamplerNames =
{ {
nameof(KnownResamplers.NearestNeighbor), nameof(KnownResamplers.NearestNeighbor), nameof(KnownResamplers.Bicubic), nameof(KnownResamplers.Box),
nameof(KnownResamplers.Bicubic),
nameof(KnownResamplers.Box),
nameof(KnownResamplers.Lanczos5), nameof(KnownResamplers.Lanczos5),
}; };
private const PixelTypes DefaultPixelType = PixelTypes.Rgba32; private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.07F);
[Theory]
[InlineData(-2, 0)]
[InlineData(-1, 0)]
[InlineData(0, 1)]
[InlineData(1, 0)]
[InlineData(2, 0)]
public static void BicubicWindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Bicubic;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
[Theory]
[InlineData(-2, 0)]
[InlineData(-1, 0)]
[InlineData(0, 1)]
[InlineData(1, 0)]
[InlineData(2, 0)]
public static void Lanczos3WindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Lanczos3;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
[Theory]
[InlineData(-4, 0)]
[InlineData(-2, 0)]
[InlineData(0, 1)]
[InlineData(2, 0)]
[InlineData(4, 0)]
public static void Lanczos5WindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Lanczos5;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
[Theory]
[InlineData(-2, 0)]
[InlineData(-1, 0)]
[InlineData(0, 1)]
[InlineData(1, 0)]
[InlineData(2, 0)]
public static void TriangleWindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Triangle;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
private const PixelTypes CommonNonDefaultPixelTypes =
PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector;
[Theory] [Theory]
[WithBasicTestPatternImages(15, 12, PixelTypes.Rgba32, 2, 3, 1, 2)] [WithBasicTestPatternImages(15, 12, PixelTypes.Rgba32, 2, 3, 1, 2)]
[WithBasicTestPatternImages(2, 256, PixelTypes.Rgba32, 1, 1, 1, 8)] [WithBasicTestPatternImages(2, 256, PixelTypes.Rgba32, 1, 1, 1, 8)]
@ -54,14 +108,117 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
var destSize = new Size(image.Width * wN / wD, image.Height * hN / hD); var destSize = new Size(image.Width * wN / wD, image.Height * hN / hD);
image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false)); image.Mutate(x => x.Resize(destSize, KnownResamplers.Bicubic, false));
FormattableString outputInfo = $"({wN}÷{wD},{hN}÷{hD})"; FormattableString outputInfo = $"({wN}÷{wD},{hN}÷{hD})";
image.DebugSave(provider, outputInfo); image.DebugSave(provider, outputInfo, appendPixelTypeToFileName: false);
image.CompareToReferenceOutput(provider, outputInfo, appendPixelTypeToFileName: false);
}
}
[Theory]
[WithTestPatternImages(100, 100, DefaultPixelType)]
public void Resize_Compand<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
image.Mutate(x => x.Resize(image.Size() / 2, true));
image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider);
}
}
[Theory]
[WithFile(TestImages.Png.Kaboom, DefaultPixelType, false)]
[WithFile(TestImages.Png.Kaboom, DefaultPixelType, true)]
public void Resize_DoesNotBleedAlphaPixels<TPixel>(TestImageProvider<TPixel> provider, bool compand)
where TPixel : struct, IPixel<TPixel>
{
string details = compand ? "Compand" : "";
provider.RunValidatingProcessorTest(
x => x.Resize(x.GetCurrentSize() / 2, compand),
details,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
[Theory]
[WithFile(TestImages.Gif.Giphy, DefaultPixelType)]
public void Resize_IsAppliedToAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2, KnownResamplers.Bicubic));
// Comparer fights decoder with gif-s. Could not use CompareToReferenceOutput here :(
image.DebugSave(provider, extension: "gif");
}
}
[Theory]
[WithTestPatternImages(50, 50, CommonNonDefaultPixelTypes)]
public void Resize_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
provider.RunValidatingProcessorTest(x => x.Resize(x.GetCurrentSize() / 2), comparer: ValidatorComparer);
}
[Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void Resize_ThrowsForWrappedMemoryImage<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image0 = provider.GetImage())
{
var mmg = TestMemoryManager<TPixel>.CreateAsCopyOf(image0.GetPixelSpan());
using (var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height))
{
Assert.ThrowsAny<Exception>(
() => { image1.Mutate(x => x.Resize(image0.Width / 2, image0.Height / 2, true)); });
}
} }
} }
[Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 1)]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 4)]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 8)]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, -1)]
public void Resize_WorksWithAllParallelismLevels<TPixel>(
TestImageProvider<TPixel> provider,
int maxDegreeOfParallelism)
where TPixel : struct, IPixel<TPixel>
{
provider.Configuration.MaxDegreeOfParallelism =
maxDegreeOfParallelism > 0 ? maxDegreeOfParallelism : Environment.ProcessorCount;
FormattableString details = $"MDP{maxDegreeOfParallelism}";
provider.RunValidatingProcessorTest(
x => x.Resize(x.GetCurrentSize() / 2),
details,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, null, null)] [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, null, null)]
[WithFileCollection(nameof(CommonTestImages), nameof(SmokeTestResamplerNames), DefaultPixelType, 0.3f, null, null)] [WithFileCollection(
[WithFileCollection(nameof(CommonTestImages), nameof(SmokeTestResamplerNames), DefaultPixelType, 1.8f, null, null)] nameof(CommonTestImages),
nameof(SmokeTestResamplerNames),
DefaultPixelType,
0.3f,
null,
null)]
[WithFileCollection(
nameof(CommonTestImages),
nameof(SmokeTestResamplerNames),
DefaultPixelType,
1.8f,
null,
null)]
[WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)] [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)]
[WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 1f, null, null)] [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 1f, null, null)]
[WithTestPatternImages(nameof(SmokeTestResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)] [WithTestPatternImages(nameof(SmokeTestResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)]
@ -84,15 +241,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
// Resize_WorksWithAllResamplers_TestPattern301x1180_NearestNeighbor-300x480.png // Resize_WorksWithAllResamplers_TestPattern301x1180_NearestNeighbor-300x480.png
// TODO: Should we investigate this? // TODO: Should we investigate this?
bool allowHigherInaccuracy = !TestEnvironment.Is64BitProcess bool allowHigherInaccuracy = !TestEnvironment.Is64BitProcess
&& string.IsNullOrEmpty(TestEnvironment.NetCoreVersion) && string.IsNullOrEmpty(TestEnvironment.NetCoreVersion)
&& sampler is NearestNeighborResampler; && sampler is NearestNeighborResampler;
var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.017f); var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.017f);
provider.RunValidatingProcessorTest( provider.RunValidatingProcessorTest(
ctx => ctx =>
{ {
SizeF newSize; SizeF newSize;
string destSizeInfo; string destSizeInfo;
if (ratio.HasValue) if (ratio.HasValue)
@ -126,107 +282,41 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
} }
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 1)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 4)] public void ResizeFromSourceRectangle<TPixel>(TestImageProvider<TPixel> provider)
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 8)]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType, -1)]
public void Resize_WorksWithAllParallelismLevels<TPixel>(TestImageProvider<TPixel> provider, int maxDegreeOfParallelism)
where TPixel : struct, IPixel<TPixel>
{
provider.Configuration.MaxDegreeOfParallelism =
maxDegreeOfParallelism > 0 ? maxDegreeOfParallelism : Environment.ProcessorCount;
FormattableString details = $"MDP{maxDegreeOfParallelism}";
provider.RunValidatingProcessorTest(
x => x.Resize(x.GetCurrentSize() / 2),
details,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
[Theory]
[WithTestPatternImages(100, 100, DefaultPixelType)]
public void Resize_Compand<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
image.Mutate(x => x.Resize(image.Size() / 2, true)); var sourceRectangle = new Rectangle(
image.Width / 8,
image.Height / 8,
image.Width / 4,
image.Height / 4);
var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2);
image.Mutate(
x => x.Resize(
image.Width,
image.Height,
KnownResamplers.Bicubic,
sourceRectangle,
destRectangle,
false));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
} }
} }
[Theory]
[WithTestPatternImages(50, 50, CommonNonDefaultPixelTypes)]
public void Resize_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
provider.RunValidatingProcessorTest(x => x.Resize(x.GetCurrentSize() / 2), comparer: ValidatorComparer);
}
[Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void Resize_ThrowsForWrappedMemoryImage<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image0 = provider.GetImage())
{
var mmg = TestMemoryManager<TPixel>.CreateAsCopyOf(image0.GetPixelSpan());
using (var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height))
{
Assert.ThrowsAny<Exception>(
() =>
{
image1.Mutate(x => x.Resize(image0.Width / 2, image0.Height / 2, true));
});
}
}
}
[Theory]
[WithFile(TestImages.Png.Kaboom, DefaultPixelType, false)]
[WithFile(TestImages.Png.Kaboom, DefaultPixelType, true)]
public void Resize_DoesNotBleedAlphaPixels<TPixel>(TestImageProvider<TPixel> provider, bool compand)
where TPixel : struct, IPixel<TPixel>
{
string details = compand ? "Compand" : "";
provider.RunValidatingProcessorTest(
x => x.Resize(x.GetCurrentSize() / 2, compand),
details,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
[Theory]
[WithFile(TestImages.Gif.Giphy, DefaultPixelType)]
public void Resize_IsAppliedToAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
image.Mutate(x => x.Resize(image.Width / 2, image.Height / 2, KnownResamplers.Bicubic));
// Comparer fights decoder with gif-s. Could not use CompareToReferenceOutput here :(
image.DebugSave(provider, extension: "gif");
}
}
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeFromSourceRectangle<TPixel>(TestImageProvider<TPixel> provider) public void ResizeHeightAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var sourceRectangle = new Rectangle(image.Width / 8, image.Height / 8, image.Width / 4, image.Height / 4); image.Mutate(x => x.Resize(0, image.Height / 3, false));
var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2);
image.Mutate(x => x.Resize(image.Width, image.Height, KnownResamplers.Bicubic, sourceRectangle, destRectangle, false));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
@ -234,27 +324,26 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
} }
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithTestPatternImages(10, 100, DefaultPixelType)]
public void ResizeWidthAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider) public void ResizeHeightCannotKeepAspectKeepsOnePixel<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
image.Mutate(x => x.Resize(image.Width / 3, 0, false)); image.Mutate(x => x.Resize(0, 5));
Assert.Equal(1, image.Width);
image.DebugSave(provider); Assert.Equal(5, image.Height);
image.CompareToReferenceOutput(ValidatorComparer, provider);
} }
} }
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeHeightAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWidthAndKeepAspect<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
image.Mutate(x => x.Resize(0, image.Height / 3, false)); image.Mutate(x => x.Resize(image.Width / 3, 0, false));
image.DebugSave(provider); image.DebugSave(provider);
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
@ -274,30 +363,17 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
} }
} }
[Theory]
[WithTestPatternImages(10, 100, DefaultPixelType)]
public void ResizeHeightCannotKeepAspectKeepsOnePixel<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
image.Mutate(x => x.Resize(0, 5));
Assert.Equal(1, image.Width);
Assert.Equal(5, image.Height);
}
}
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeWithCropWidthMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithBoxPadMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions
{ {
Size = new Size(image.Width / 2, image.Height) Size = new Size(image.Width + 200, image.Height + 200), Mode = ResizeMode.BoxPad
}; };
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -313,10 +389,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions { Size = new Size(image.Width, image.Height / 2) };
{
Size = new Size(image.Width, image.Height / 2)
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -327,16 +400,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeWithPadMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithCropWidthMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions { Size = new Size(image.Width / 2, image.Height) };
{
Size = new Size(image.Width + 200, image.Height),
Mode = ResizeMode.Pad
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -347,16 +416,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeWithBoxPadMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithMaxMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions { Size = new Size(300, 300), Mode = ResizeMode.Max };
{
Size = new Size(image.Width + 200, image.Height + 200),
Mode = ResizeMode.BoxPad
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -367,16 +432,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeWithMaxMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithMinMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions
{ {
Size = new Size(300, 300), Size = new Size(
Mode = ResizeMode.Max (int)Math.Round(image.Width * .75F),
}; (int)Math.Round(image.Height * .95F)),
Mode = ResizeMode.Min
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -387,16 +454,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
[Theory] [Theory]
[WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
public void ResizeWithMinMode<TPixel>(TestImageProvider<TPixel> provider) public void ResizeWithPadMode<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions
{ {
Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * .95F)), Size = new Size(image.Width + 200, image.Height), Mode = ResizeMode.Pad
Mode = ResizeMode.Min };
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -413,10 +479,9 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
using (Image<TPixel> image = provider.GetImage()) using (Image<TPixel> image = provider.GetImage())
{ {
var options = new ResizeOptions var options = new ResizeOptions
{ {
Size = new Size(image.Width / 2, image.Height), Size = new Size(image.Width / 2, image.Height), Mode = ResizeMode.Stretch
Mode = ResizeMode.Stretch };
};
image.Mutate(x => x.Resize(options)); image.Mutate(x => x.Resize(options));
@ -424,61 +489,5 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
image.CompareToReferenceOutput(ValidatorComparer, provider); image.CompareToReferenceOutput(ValidatorComparer, provider);
} }
} }
[Theory]
[InlineData(-2, 0)]
[InlineData(-1, 0)]
[InlineData(0, 1)]
[InlineData(1, 0)]
[InlineData(2, 0)]
public static void BicubicWindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Bicubic;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
[Theory]
[InlineData(-2, 0)]
[InlineData(-1, 0)]
[InlineData(0, 1)]
[InlineData(1, 0)]
[InlineData(2, 0)]
public static void TriangleWindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Triangle;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
[Theory]
[InlineData(-2, 0)]
[InlineData(-1, 0)]
[InlineData(0, 1)]
[InlineData(1, 0)]
[InlineData(2, 0)]
public static void Lanczos3WindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Lanczos3;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
[Theory]
[InlineData(-4, 0)]
[InlineData(-2, 0)]
[InlineData(0, 1)]
[InlineData(2, 0)]
[InlineData(4, 0)]
public static void Lanczos5WindowOscillatesCorrectly(float x, float expected)
{
IResampler sampler = KnownResamplers.Lanczos5;
float result = sampler.GetValue(x);
Assert.Equal(result, expected);
}
} }
} }
Loading…
Cancel
Save