diff --git a/src/ImageSharp/Common/Helpers/Vector4Utils.cs b/src/ImageSharp/Common/Helpers/Vector4Utils.cs
index 5c122217d..a4e0921d0 100644
--- a/src/ImageSharp/Common/Helpers/Vector4Utils.cs
+++ b/src/ImageSharp/Common/Helpers/Vector4Utils.cs
@@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp
}
///
- /// Bulk variant of
+ /// Bulk variant of .
///
/// The span of vectors
/// The transformation matrix.
diff --git a/src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor.cs
index d2e9630dc..83746952c 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor.cs
@@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
public DenseMatrix KernelY { get; }
///
- public bool Grayscale { get; set; }
+ public bool Grayscale { get; }
///
protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
diff --git a/tests/ImageSharp.Tests/FileTestBase.cs b/tests/ImageSharp.Tests/FileTestBase.cs
index efd6c3b40..a056bc474 100644
--- a/tests/ImageSharp.Tests/FileTestBase.cs
+++ b/tests/ImageSharp.Tests/FileTestBase.cs
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using System;
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Tests
@@ -8,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests
///
/// The test base class for reading and writing to files.
///
+ [Obsolete("See: https://github.com/SixLabors/ImageSharp/issues/868")]
public abstract class FileTestBase
{
///
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/Basic1ParameterConvolutionTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/Basic1ParameterConvolutionTests.cs
new file mode 100644
index 000000000..1f939a281
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/Basic1ParameterConvolutionTests.cs
@@ -0,0 +1,56 @@
+// // Copyright (c) Six Labors and contributors.
+// // Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+using SixLabors.Primitives;
+
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
+{
+ [GroupOutput("Convolution")]
+ public abstract class Basic1ParameterConvolutionTests
+ {
+ private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05F);
+
+ public static readonly TheoryData Values = new TheoryData { 3, 5 };
+
+ public static readonly string[] InputImages =
+ {
+ TestImages.Bmp.Car,
+ TestImages.Png.CalliphoraPartial
+ };
+
+ [Theory]
+ [WithFileCollection(nameof(InputImages), nameof(Values), PixelTypes.Rgba32)]
+ public void OnFullImage(TestImageProvider provider, int value)
+ where TPixel : struct, IPixel
+ {
+ provider.Utility.TestGroupName = this.GetType().Name;
+ provider.RunValidatingProcessorTest(
+ x => this.Apply(x, value),
+ value,
+ ValidatorComparer);
+ }
+
+ [Theory]
+ [WithFileCollection(nameof(InputImages), nameof(Values), PixelTypes.Rgba32)]
+ public void InBox(TestImageProvider provider, int value)
+ where TPixel : struct, IPixel
+ {
+ provider.Utility.TestGroupName = this.GetType().Name;
+ provider.RunRectangleConstrainedValidatingProcessorTest(
+ (x, rect) => this.Apply(x, value, rect),
+ value,
+ ValidatorComparer);
+ }
+
+ protected abstract void Apply(IImageProcessingContext ctx, int value)
+ where TPixel : struct, IPixel;
+
+ protected abstract void Apply(IImageProcessingContext ctx, int value, Rectangle bounds)
+ where TPixel : struct, IPixel;
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BoxBlurTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BoxBlurTest.cs
index 1f0d12cf7..923f9d616 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/BoxBlurTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/BoxBlurTest.cs
@@ -1,51 +1,17 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
-using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
-
using SixLabors.Primitives;
-using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
{
- public class BoxBlurTest : FileTestBase
+ [GroupOutput("Convolution")]
+ public class BoxBlurTest : Basic1ParameterConvolutionTests
{
- public static readonly TheoryData BoxBlurValues
- = new TheoryData
- {
- 3,
- 5
- };
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(BoxBlurValues), DefaultPixelType)]
- public void ImageShouldApplyBoxBlurFilter(TestImageProvider provider, int value)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.BoxBlur(value));
- image.DebugSave(provider, value);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(BoxBlurValues), DefaultPixelType)]
- public void ImageShouldApplyBoxBlurFilterInBox(TestImageProvider provider, int value)
- where TPixel : struct, IPixel
- {
- using (Image source = provider.GetImage())
- using (Image image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.BoxBlur(value, bounds));
- image.DebugSave(provider, value);
+ protected override void Apply(IImageProcessingContext ctx, int value) => ctx.BoxBlur(value);
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, int value, Rectangle bounds) =>
+ ctx.BoxBlur(value, bounds);
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs
index b6a7741b3..05524b20b 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs
@@ -10,13 +10,16 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
{
- public class DetectEdgesTest : FileTestBase
+ [GroupOutput("Convolution")]
+ public class DetectEdgesTest
{
// I think our comparison is not accurate enough (nor can be) for RgbaVector.
// The image pixels are identical according to BeyondCompare.
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.0456F);
- public static readonly string[] CommonTestImages = { TestImages.Png.Bike };
+ public static readonly string[] TestImages = { Tests.TestImages.Png.Bike };
+
+ public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector;
public static readonly TheoryData DetectEdgesFilters = new TheoryData
{
@@ -33,7 +36,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
};
[Theory]
- [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
+ [WithFileCollection(nameof(TestImages), PixelTypes.Rgba32)]
public void DetectEdges_WorksOnWrappedMemoryImage(TestImageProvider provider)
where TPixel : struct, IPixel
{
@@ -49,8 +52,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
}
[Theory]
- [WithTestPatternImages(nameof(DetectEdgesFilters), 100, 100, DefaultPixelType)]
- [WithFileCollection(nameof(CommonTestImages), nameof(DetectEdgesFilters), DefaultPixelType)]
+ [WithTestPatternImages(nameof(DetectEdgesFilters), 100, 100, PixelTypes.Rgba32)]
+ [WithFileCollection(nameof(TestImages), nameof(DetectEdgesFilters), PixelTypes.Rgba32)]
public void DetectEdges_WorksWithAllFilters(TestImageProvider provider, EdgeDetectionOperators detector)
where TPixel : struct, IPixel
{
@@ -63,7 +66,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
}
[Theory]
- [WithFileCollection(nameof(CommonTestImages), CommonNonDefaultPixelTypes)]
+ [WithFileCollection(nameof(TestImages), CommonNonDefaultPixelTypes)]
public void DetectEdges_IsNotBoundToSinglePixelType(TestImageProvider provider)
where TPixel : struct, IPixel
{
@@ -76,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
}
[Theory]
- [WithFile(TestImages.Gif.Giphy, DefaultPixelType)]
+ [WithFile(Tests.TestImages.Gif.Giphy, PixelTypes.Rgba32)]
public void DetectEdges_IsAppliedToAllFrames(TestImageProvider provider)
where TPixel : struct, IPixel
{
@@ -88,7 +91,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
}
[Theory]
- [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)]
+ [WithFileCollection(nameof(TestImages), PixelTypes.Rgba32)]
public void DetectEdges_InBox(TestImageProvider provider)
where TPixel : struct, IPixel
{
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs
index 6bd3b34bb..6307a1c51 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs
@@ -10,37 +10,12 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
{
- public class GaussianBlurTest : FileTestBase
+ [GroupOutput("Convolution")]
+ public class GaussianBlurTest : Basic1ParameterConvolutionTests
{
- public static readonly TheoryData GaussianBlurValues = new TheoryData { 3, 5 };
+ protected override void Apply(IImageProcessingContext ctx, int value) => ctx.GaussianBlur(value);
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(GaussianBlurValues), DefaultPixelType)]
- public void ImageShouldApplyGaussianBlurFilter(TestImageProvider provider, int value)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.GaussianBlur(value));
- image.DebugSave(provider, value);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(GaussianBlurValues), DefaultPixelType)]
- public void ImageShouldApplyGaussianBlurFilterInBox(TestImageProvider provider, int value)
- where TPixel : struct, IPixel
- {
- using (Image source = provider.GetImage())
- using (Image image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.GaussianBlur(value, bounds));
- image.DebugSave(provider, value);
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, int value, Rectangle bounds) =>
+ ctx.GaussianBlur(value, bounds);
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianSharpenTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianSharpenTest.cs
index 8eb1f85eb..29a1643b0 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianSharpenTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianSharpenTest.cs
@@ -9,42 +9,12 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution
{
- public class GaussianSharpenTest : FileTestBase
+ [GroupOutput("Convolution")]
+ public class GaussianSharpenTest : Basic1ParameterConvolutionTests
{
- public static readonly TheoryData GaussianSharpenValues
- = new TheoryData
- {
- 3,
- 5
- };
+ protected override void Apply(IImageProcessingContext ctx, int value) => ctx.GaussianSharpen(value);
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(GaussianSharpenValues), DefaultPixelType)]
- public void ImageShouldApplyGaussianSharpenFilter(TestImageProvider provider, int value)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.GaussianSharpen(value));
- image.DebugSave(provider, value);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(GaussianSharpenValues), DefaultPixelType)]
- public void ImageShouldApplyGaussianSharpenFilterInBox(TestImageProvider provider, int value)
- where TPixel : struct, IPixel
- {
- using (Image source = provider.GetImage())
- using (var image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.GaussianSharpen(value, bounds));
- image.DebugSave(provider, value);
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, int value, Rectangle bounds) =>
+ ctx.GaussianSharpen(value, bounds);
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs
index 9774cb50c..cb901c2a8 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs
@@ -2,129 +2,153 @@
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+using SixLabors.ImageSharp.Primitives;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Dithering;
using SixLabors.ImageSharp.Processing.Processors.Dithering;
+using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
+
using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization
{
- public class DitherTests : FileTestBase
+ public class DitherTests
{
- public static readonly string[] CommonTestImages =
- {
- TestImages.Png.CalliphoraPartial, TestImages.Png.Bike
- };
-
- public static readonly TheoryData OrderedDitherers = new TheoryData
- {
- { "Bayer8x8", KnownDitherers.BayerDither8x8 },
- { "Bayer4x4", KnownDitherers.BayerDither4x4 },
- { "Ordered3x3", KnownDitherers.OrderedDither3x3 },
- { "Bayer2x2", KnownDitherers.BayerDither2x2 }
- };
-
- public static readonly TheoryData ErrorDiffusers = new TheoryData
- {
- { "Atkinson", KnownDiffusers.Atkinson },
- { "Burks", KnownDiffusers.Burks },
- { "FloydSteinberg", KnownDiffusers.FloydSteinberg },
- { "JarvisJudiceNinke", KnownDiffusers.JarvisJudiceNinke },
- { "Sierra2", KnownDiffusers.Sierra2 },
- { "Sierra3", KnownDiffusers.Sierra3 },
- { "SierraLite", KnownDiffusers.SierraLite },
- { "StevensonArce", KnownDiffusers.StevensonArce },
- { "Stucki", KnownDiffusers.Stucki },
- };
-
+ public const PixelTypes CommonNonDefaultPixelTypes =
+ PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Rgb24 | PixelTypes.RgbaVector;
+
+ public static readonly string[] CommonTestImages = { TestImages.Png.CalliphoraPartial, TestImages.Png.Bike };
+
+ public static readonly TheoryData ErrorDiffusers = new TheoryData
+ {
+ KnownDiffusers.Atkinson,
+ KnownDiffusers.Burks,
+ KnownDiffusers.FloydSteinberg,
+ KnownDiffusers.JarvisJudiceNinke,
+ KnownDiffusers.Sierra2,
+ KnownDiffusers.Sierra3,
+ KnownDiffusers.SierraLite,
+ KnownDiffusers.StevensonArce,
+ KnownDiffusers.Stucki,
+ };
+
+ public static readonly TheoryData OrderedDitherers = new TheoryData
+ {
+ KnownDitherers.BayerDither8x8,
+ KnownDitherers.BayerDither4x4,
+ KnownDitherers.OrderedDither3x3,
+ KnownDitherers.BayerDither2x2
+ };
+ private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05f);
+
private static IOrderedDither DefaultDitherer => KnownDitherers.BayerDither4x4;
private static IErrorDiffuser DefaultErrorDiffuser => KnownDiffusers.Atkinson;
+ ///
+ /// The output is visually correct old 32bit runtime,
+ /// but it is very different because of floating point inaccuracies.
+ ///
+ private static readonly bool SkipAllDitherTests =
+ !TestEnvironment.Is64BitProcess && string.IsNullOrEmpty(TestEnvironment.NetCoreVersion);
+
[Theory]
- [WithFileCollection(nameof(CommonTestImages), nameof(OrderedDitherers), DefaultPixelType)]
- [WithTestPatternImages(nameof(OrderedDitherers), 100, 100, DefaultPixelType)]
- public void DitherFilter_WorksWithAllDitherers(TestImageProvider provider, string name, IOrderedDither ditherer)
+ [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)]
+ public void ApplyDiffusionFilterInBox(TestImageProvider provider)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
+ if (SkipAllDitherTests)
{
- image.Mutate(x => x.Dither(ditherer));
- image.DebugSave(provider, name);
+ return;
}
+
+ provider.RunRectangleConstrainedValidatingProcessorTest(
+ (x, rect) => x.Diffuse(DefaultErrorDiffuser, .5F, rect),
+ comparer: ValidatorComparer);
}
[Theory]
- [WithFileCollection(nameof(CommonTestImages), nameof(ErrorDiffusers), DefaultPixelType)]
- [WithTestPatternImages(nameof(ErrorDiffusers), 100, 100, DefaultPixelType)]
- public void DiffusionFilter_WorksWithAllErrorDiffusers(TestImageProvider provider, string name, IErrorDiffuser diffuser)
+ [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)]
+ public void ApplyDitherFilterInBox(TestImageProvider provider)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
+ if (SkipAllDitherTests)
{
- image.Mutate(x => x.Diffuse(diffuser, .5F));
- image.DebugSave(provider, name);
+ return;
}
+
+ provider.RunRectangleConstrainedValidatingProcessorTest(
+ (x, rect) => x.Dither(DefaultDitherer, rect),
+ comparer: ValidatorComparer);
}
[Theory]
[WithFile(TestImages.Png.Filter0, CommonNonDefaultPixelTypes)]
- public void DitherFilter_ShouldNotDependOnSinglePixelType(TestImageProvider provider)
+ public void DiffusionFilter_ShouldNotDependOnSinglePixelType(TestImageProvider provider)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
+ if (SkipAllDitherTests)
{
- image.Mutate(x => x.Dither(DefaultDitherer));
- image.DebugSave(provider);
+ return;
}
+
+ // Increased tolerance because of compatibility issues on .NET 4.6.2:
+ var comparer = ImageComparer.TolerantPercentage(1f);
+ provider.RunValidatingProcessorTest(x => x.Diffuse(DefaultErrorDiffuser, 0.5f), comparer: comparer);
}
[Theory]
- [WithFile(TestImages.Png.Filter0, CommonNonDefaultPixelTypes)]
- public void DiffusionFilter_ShouldNotDependOnSinglePixelType(TestImageProvider provider)
+ [WithFileCollection(nameof(CommonTestImages), nameof(ErrorDiffusers), PixelTypes.Rgba32)]
+ public void DiffusionFilter_WorksWithAllErrorDiffusers(
+ TestImageProvider provider,
+ IErrorDiffuser diffuser)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
+ if (SkipAllDitherTests)
{
- image.Mutate(x => x.Diffuse(DefaultErrorDiffuser, 0.5f));
- image.DebugSave(provider);
+ return;
}
+
+ provider.RunValidatingProcessorTest(
+ x => x.Diffuse(diffuser, 0.5f),
+ testOutputDetails: diffuser.GetType().Name,
+ comparer: ValidatorComparer,
+ appendPixelTypeToFileName: false);
}
[Theory]
- [WithFile(TestImages.Png.CalliphoraPartial, DefaultPixelType)]
- public void ApplyDitherFilterInBox(TestImageProvider provider)
+ [WithFile(TestImages.Png.Filter0, CommonNonDefaultPixelTypes)]
+ public void DitherFilter_ShouldNotDependOnSinglePixelType(TestImageProvider provider)
where TPixel : struct, IPixel
{
- using (Image source = provider.GetImage())
- using (Image image = source.Clone())
+ if (SkipAllDitherTests)
{
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.Dither(DefaultDitherer, bounds));
- image.DebugSave(provider);
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
+ return;
}
+
+ provider.RunValidatingProcessorTest(
+ x => x.Dither(DefaultDitherer),
+ comparer: ValidatorComparer);
}
[Theory]
- [WithFile(TestImages.Png.CalliphoraPartial, DefaultPixelType)]
- public void ApplyDiffusionFilterInBox(TestImageProvider provider)
+ [WithFileCollection(nameof(CommonTestImages), nameof(OrderedDitherers), PixelTypes.Rgba32)]
+ public void DitherFilter_WorksWithAllDitherers(
+ TestImageProvider provider,
+ IOrderedDither ditherer)
where TPixel : struct, IPixel
{
- using (Image source = provider.GetImage())
- using (Image image = source.Clone())
+ if (SkipAllDitherTests)
{
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.Diffuse(DefaultErrorDiffuser, .5F, bounds));
- image.DebugSave(provider);
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
+ return;
}
+
+ provider.RunValidatingProcessorTest(
+ x => x.Dither(ditherer),
+ testOutputDetails: ditherer.GetType().Name,
+ comparer: ValidatorComparer,
+ appendPixelTypeToFileName: false);
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/BackgroundColorTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/BackgroundColorTest.cs
index 792c7b080..d7f77c956 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Effects/BackgroundColorTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/BackgroundColorTest.cs
@@ -10,35 +10,30 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects
{
- public class BackgroundColorTest : FileTestBase
+ [GroupOutput("Effects")]
+ public class BackgroundColorTest
{
+ public static readonly string[] InputImages =
+ {
+ TestImages.Png.Splash,
+ TestImages.Png.Ducky
+ };
+
[Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyBackgroundColorFilter(TestImageProvider provider)
+ [WithFileCollection(nameof(InputImages), PixelTypes.Rgba32)]
+ public void FullImage(TestImageProvider provider)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.BackgroundColor(NamedColors.HotPink));
- image.DebugSave(provider);
- }
+ provider.RunValidatingProcessorTest(x => x.BackgroundColor(NamedColors.HotPink));
}
[Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyBackgroundColorFilterInBox(TestImageProvider provider)
+ [WithFileCollection(nameof(InputImages), PixelTypes.Rgba32)]
+ public void InBox(TestImageProvider provider)
where TPixel : struct, IPixel
{
- using (Image source = provider.GetImage())
- using (var image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.BackgroundColor(NamedColors.HotPink, bounds));
- image.DebugSave(provider);
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
+ provider.RunRectangleConstrainedValidatingProcessorTest(
+ (x, rect) => x.BackgroundColor(NamedColors.HotPink, rect));
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs
index d4429aaf3..ea2273cd5 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs
@@ -10,40 +10,40 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects
{
- public class OilPaintTest : FileTestBase
+ [GroupOutput("Effects")]
+ public class OilPaintTest
{
public static readonly TheoryData OilPaintValues = new TheoryData
{
- { 15, 10 }, { 6, 5 }
+ { 15, 10 },
+ { 6, 5 }
};
+ public static readonly string[] InputImages =
+ {
+ TestImages.Png.CalliphoraPartial,
+ TestImages.Bmp.Car
+ };
[Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(OilPaintValues), DefaultPixelType)]
- public void ApplyOilPaintFilter(TestImageProvider provider, int levels, int brushSize)
+ [WithFileCollection(nameof(InputImages), nameof(OilPaintValues), PixelTypes.Rgba32)]
+ public void FullImage(TestImageProvider provider, int levels, int brushSize)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.OilPaint(levels, brushSize));
- image.DebugSave(provider, string.Join("-", levels, brushSize));
- }
+ provider.RunValidatingProcessorTest(
+ x => x.OilPaint(levels, brushSize),
+ $"{levels}-{brushSize}",
+ appendPixelTypeToFileName: false);
}
[Theory]
- [WithFileCollection(nameof(DefaultFiles), nameof(OilPaintValues), DefaultPixelType)]
- public void ApplyOilPaintFilterInBox(TestImageProvider provider, int levels, int brushSize)
+ [WithFileCollection(nameof(InputImages), nameof(OilPaintValues), PixelTypes.Rgba32)]
+ [WithTestPatternImages(nameof(OilPaintValues), 100, 100, PixelTypes.Rgba32)]
+ public void InBox(TestImageProvider provider, int levels, int brushSize)
where TPixel : struct, IPixel
{
- using (Image source = provider.GetImage())
- using (Image image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.OilPaint(levels, brushSize, bounds));
- image.DebugSave(provider, string.Join("-", levels, brushSize));
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
+ provider.RunRectangleConstrainedValidatingProcessorTest(
+ (x, rect) => x.OilPaint(levels, brushSize, rect),
+ $"{levels}-{brushSize}");
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelateTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelateTest.cs
index cb9a0ba0c..726f4b707 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelateTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelateTest.cs
@@ -4,82 +4,32 @@
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
-
using SixLabors.Primitives;
+
using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects
{
- public class PixelateTest : FileTestBase
+ [GroupOutput("Effects")]
+ public class PixelateTest
{
- public static readonly TheoryData PixelateValues
- = new TheoryData
- {
- 4 ,
- 8
- };
+ public static readonly TheoryData PixelateValues = new TheoryData { 4, 8 };
[Theory]
- [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.Rgba32)]
- public void ImageShouldApplyPixelateFilter(TestImageProvider provider, int value)
+ [WithFile(TestImages.Png.Ducky, nameof(PixelateValues), PixelTypes.Rgba32)]
+ public void FullImage(TestImageProvider provider, int value)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Pixelate(value));
- image.DebugSave(provider, value);
-
- // Test the neigbouring pixels
- for (int y = 0; y < image.Height; y += value)
- {
- for (int x = 0; x < image.Width; x += value)
- {
- TPixel source = image[x, y];
- for (int pixY = y; pixY < y + value && pixY < image.Height; pixY++)
- {
- for (int pixX = x; pixX < x + value && pixX < image.Width; pixX++)
- {
- Assert.Equal(source, image[pixX, pixY]);
- }
- }
- }
- }
- }
+ provider.RunValidatingProcessorTest(x => x.Pixelate(value), value, appendPixelTypeToFileName: false);
}
[Theory]
[WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.Rgba32)]
- public void ImageShouldApplyPixelateFilterInBox(TestImageProvider provider, int value)
+ [WithFile(TestImages.Png.CalliphoraPartial, nameof(PixelateValues), PixelTypes.Rgba32)]
+ public void InBox(TestImageProvider provider, int value)
where TPixel : struct, IPixel
{
- using (Image source = provider.GetImage())
- using (var image = source.Clone())
- {
- var bounds = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.Pixelate(value, bounds));
- image.DebugSave(provider, value);
-
- for (int y = 0; y < image.Height; y++)
- {
- for (int x = 0; x < image.Width; x++)
- {
- int tx = x;
- int ty = y;
- TPixel sourceColor = source[tx, ty];
- if (bounds.Contains(tx, ty))
- {
- int sourceX = tx - ((tx - bounds.Left) % value) + (value / 2);
- int sourceY = ty - ((ty - bounds.Top) % value) + (value / 2);
-
- sourceColor = image[sourceX, sourceY];
- }
- Assert.Equal(sourceColor, image[tx, ty]);
- }
- }
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
+ provider.RunRectangleConstrainedValidatingProcessorTest((x, rect) => x.Pixelate(value, rect), value);
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Overlays/GlowTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Overlays/GlowTest.cs
index 479ee346a..113c13b8a 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Overlays/GlowTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Overlays/GlowTest.cs
@@ -10,59 +10,14 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Overlays
{
- public class GlowTest : FileTestBase
+ [GroupOutput("Overlays")]
+ public class GlowTest : OverlayTestBase
{
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyGlowFilter(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Glow());
- image.DebugSave(provider);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, T color) => ctx.Glow(color);
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyGlowFilterColor(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Glow(NamedColors.Orange));
- image.DebugSave(provider);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, float radiusX, float radiusY) =>
+ ctx.Glow(radiusX);
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyGlowFilterRadius(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Glow(image.Width / 4F));
- image.DebugSave(provider);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyGlowFilterInBox(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image source = provider.GetImage())
- using (var image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
-
- image.Mutate(x => x.Glow(bounds));
- image.DebugSave(provider);
-
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, Rectangle rect) => ctx.Glow(rect);
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Overlays/OverlayTestBase.cs b/tests/ImageSharp.Tests/Processing/Processors/Overlays/OverlayTestBase.cs
new file mode 100644
index 000000000..d2abcd731
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/Processors/Overlays/OverlayTestBase.cs
@@ -0,0 +1,70 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Reflection;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+using SixLabors.Primitives;
+
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Processors.Overlays
+{
+ [GroupOutput("Overlays")]
+ public abstract class OverlayTestBase
+ {
+ public static string[] ColorNames = { "Blue", "White" };
+
+ public static string[] InputImages = { TestImages.Png.Ducky, TestImages.Png.Splash };
+
+ private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05f);
+
+ [Theory]
+ [WithFileCollection(nameof(InputImages), nameof(ColorNames), PixelTypes.Rgba32)]
+ public void FullImage_ApplyColor(TestImageProvider provider, string colorName)
+ where TPixel : struct, IPixel
+ {
+ provider.Utility.TestGroupName = this.GetType().Name;
+ var f = (FieldInfo)typeof(NamedColors).GetMember(colorName)[0];
+ TPixel color = (TPixel)f.GetValue(null);
+
+ provider.RunValidatingProcessorTest(x => this.Apply(x, color), colorName, ValidatorComparer, appendPixelTypeToFileName: false);
+ }
+
+ [Theory]
+ [WithFileCollection(nameof(InputImages), PixelTypes.Rgba32)]
+ public void FullImage_ApplyRadius(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ provider.Utility.TestGroupName = this.GetType().Name;
+ provider.RunValidatingProcessorTest(
+ x =>
+ {
+ Size size = x.GetCurrentSize();
+ this.Apply(x, size.Width / 4f, size.Height / 4f);
+ },
+ comparer: ValidatorComparer,
+ appendPixelTypeToFileName: false);
+ }
+
+ [Theory]
+ [WithFileCollection(nameof(InputImages), PixelTypes.Rgba32)]
+ public void InBox(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ provider.Utility.TestGroupName = this.GetType().Name;
+ provider.RunRectangleConstrainedValidatingProcessorTest((x, rect) => this.Apply(x, rect));
+ }
+
+ protected abstract void Apply(IImageProcessingContext ctx, T color)
+ where T : struct, IPixel;
+
+ protected abstract void Apply(IImageProcessingContext ctx, float radiusX, float radiusY)
+ where T : struct, IPixel;
+
+ protected abstract void Apply(IImageProcessingContext ctx, Rectangle rect)
+ where T : struct, IPixel;
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Overlays/VignetteTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Overlays/VignetteTest.cs
index 3a378a095..ad04a827d 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Overlays/VignetteTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Overlays/VignetteTest.cs
@@ -1,68 +1,19 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
-using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
-
using SixLabors.Primitives;
-using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Overlays
{
- public class VignetteTest : FileTestBase
+ [GroupOutput("Overlays")]
+ public class VignetteTest : OverlayTestBase
{
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyVignetteFilter(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Vignette());
- image.DebugSave(provider);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyVignetteFilterColor(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Vignette(NamedColors.Orange));
- image.DebugSave(provider);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyVignetteFilterRadius(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image image = provider.GetImage())
- {
- image.Mutate(x => x.Vignette(image.Width / 4F, image.Height / 4F));
- image.DebugSave(provider);
- }
- }
-
- [Theory]
- [WithFileCollection(nameof(DefaultFiles), DefaultPixelType)]
- public void ImageShouldApplyVignetteFilterInBox(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image source = provider.GetImage())
- using (var image = source.Clone())
- {
- var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
+ protected override void Apply(IImageProcessingContext ctx, T color) => ctx.Vignette(color);
- image.Mutate(x => x.Vignette(bounds));
- image.DebugSave(provider);
+ protected override void Apply(IImageProcessingContext ctx, float radiusX, float radiusY) =>
+ ctx.Vignette(radiusX, radiusY);
- ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds);
- }
- }
+ protected override void Apply(IImageProcessingContext ctx, Rectangle rect) => ctx.Vignette(rect);
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs
index 28b01061e..6dc9b3630 100644
--- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AutoOrientTests.cs
@@ -6,27 +6,16 @@ using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
+using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+
using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{
- public class AutoOrientTests : FileTestBase
+ [GroupOutput("Transforms")]
+ public class AutoOrientTests
{
- public static readonly string[] FlipFiles = { TestImages.Bmp.F };
-
- public static readonly TheoryData OrientationValues
- = new TheoryData
- {
- { RotateMode.None, FlipMode.None, 0 },
- { RotateMode.None, FlipMode.None, 1 },
- { RotateMode.None, FlipMode.Horizontal, 2 },
- { RotateMode.Rotate180, FlipMode.None, 3 },
- { RotateMode.Rotate180, FlipMode.Horizontal, 4 },
- { RotateMode.Rotate90, FlipMode.Horizontal, 5 },
- { RotateMode.Rotate270, FlipMode.None, 6 },
- { RotateMode.Rotate90, FlipMode.Vertical, 7 },
- { RotateMode.Rotate90, FlipMode.None, 8 },
- };
+ public const string FlipTestFile = TestImages.Bmp.F;
public static readonly TheoryData InvalidOrientationValues
= new TheoryData
@@ -38,27 +27,38 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{ ExifDataType.SignedLong, BitConverter.GetBytes((int) 5) }
};
+ public static readonly TheoryData ExifOrientationValues = new TheoryData()
+ {
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8
+ };
+
[Theory]
- [WithFileCollection(nameof(FlipFiles), nameof(OrientationValues), DefaultPixelType)]
- public void ImageShouldAutoRotate(TestImageProvider provider, RotateMode rotateType, FlipMode flipType, ushort orientation)
+ [WithFile(FlipTestFile, nameof(ExifOrientationValues), PixelTypes.Rgba32)]
+ public void AutoOrient_WorksForAllExifOrientations(TestImageProvider provider, ushort orientation)
where TPixel : struct, IPixel
{
using (Image image = provider.GetImage())
{
image.Metadata.ExifProfile = new ExifProfile();
image.Metadata.ExifProfile.SetValue(ExifTag.Orientation, orientation);
-
- image.Mutate(x => x.RotateFlip(rotateType, flipType));
- image.DebugSave(provider, string.Join("_", rotateType, flipType, orientation, "1_before"));
-
+
image.Mutate(x => x.AutoOrient());
- image.DebugSave(provider, string.Join("_", rotateType, flipType, orientation, "2_after"));
+ image.DebugSave(provider, orientation, appendPixelTypeToFileName: false);
+ image.CompareToReferenceOutput(provider, orientation, appendPixelTypeToFileName: false);
}
}
[Theory]
- [WithFileCollection(nameof(FlipFiles), nameof(InvalidOrientationValues), DefaultPixelType)]
- public void ImageShouldAutoRotateInvalidValues(TestImageProvider provider, ExifDataType dataType, byte[] orientation)
+ [WithFile(FlipTestFile, nameof(InvalidOrientationValues), PixelTypes.Rgba32)]
+ public void AutoOrient_WorksWithCorruptExifData(TestImageProvider provider, ExifDataType dataType, byte[] orientation)
where TPixel : struct, IPixel
{
var profile = new ExifProfile();
@@ -72,11 +72,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
bytes[18] = (byte)dataType;
// Change the number of components
bytes[20] = 1;
+
+ byte[] orientationCodeData = new byte[8];
+ Array.Copy(orientation, orientationCodeData, orientation.Length);
+
+ ulong orientationCode = BitConverter.ToUInt64(orientationCodeData, 0);
using (Image image = provider.GetImage())
+ using (Image