diff --git a/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs index 90f994f366..05aa3c2d35 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs @@ -35,7 +35,7 @@ namespace ImageSharp.Tests.Formats.Png using (Image img2 = Image.Load(ms, new PngDecoder())) { // img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder()); - ImageComparer.CheckSimilarity(image, img2); + ImageComparer.VerifySimilarity(image, img2); } } } @@ -56,7 +56,7 @@ namespace ImageSharp.Tests.Formats.Png using (Image img2 = Image.Load(ms, new PngDecoder())) { // img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder()); - ImageComparer.CheckSimilarity(image, img2, 0.03f); + ImageComparer.VerifySimilarity(image, img2, 0.03f); } } } @@ -121,7 +121,7 @@ namespace ImageSharp.Tests.Formats.Png ms.Position = 0; using (Image img2 = Image.Load(ms, new PngDecoder())) { - ImageComparer.CheckSimilarity(image, img2); + ImageComparer.VerifySimilarity(image, img2); } } } diff --git a/tests/ImageSharp.Tests/ImageComparer.cs b/tests/ImageSharp.Tests/ImageComparer.cs index 4a37c6c459..30e89918c0 100644 --- a/tests/ImageSharp.Tests/ImageComparer.cs +++ b/tests/ImageSharp.Tests/ImageComparer.cs @@ -17,9 +17,9 @@ namespace ImageSharp.Tests /// public static class ImageComparer { - const int DefaultScalingFactor = 32; // This is means the images get scaled into a 32x32 image to sample pixels - const int DefaultSegmentThreshold = 3; // The greyscale difference between 2 segements my be > 3 before it influences the overall difference - const float DefaultImageThreshold = 0.000F; // After segment thresholds the images must have no differences + internal const int DefaultScalingFactor = 32; // This is means the images get scaled into a 32x32 image to sample pixels + internal const int DefaultSegmentThreshold = 3; // The greyscale difference between 2 segements my be > 3 before it influences the overall difference + internal const float DefaultImageThreshold = 0.000F; // After segment thresholds the images must have no differences /// /// Fills the bounded area with a solid color and does a visual comparison between 2 images asserting the difference outwith @@ -50,7 +50,7 @@ namespace ImageSharp.Tests expected.Fill(NamedColors.HotPink, bounds); actual.Fill(NamedColors.HotPink, bounds); - CheckSimilarity(expected, actual, imageTheshold, segmentThreshold, scalingFactor); + VerifySimilarity(expected, actual, imageTheshold, segmentThreshold, scalingFactor); } /// @@ -72,7 +72,7 @@ namespace ImageSharp.Tests /// This is a sampling factor we sample a grid of average pixels width by high /// The default undefined value is /// - public static void CheckSimilarity( + public static void VerifySimilarity( Image expected, Image actual, float imageTheshold = DefaultImageThreshold, @@ -80,6 +80,9 @@ namespace ImageSharp.Tests int scalingFactor = DefaultScalingFactor) where TPixelA : struct, IPixel where TPixelB : struct, IPixel { + Assert.Equal(expected.Width, actual.Width); + Assert.Equal(expected.Height, actual.Height); + float percentage = expected.PercentageDifference(actual, segmentThreshold, scalingFactor); Assert.InRange(percentage, 0, imageTheshold); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs index fb195254e3..9835a3e3aa 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs @@ -40,7 +40,7 @@ namespace ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { image.Resize(image.Width / 2, image.Height / 2, sampler, true) - .DebugSave(provider, name, Extensions.Bmp); + .CompareToReferenceOutput(provider, name); } } diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Bicubic.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Bicubic.png new file mode 100644 index 0000000000..026630f3fc Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Bicubic.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Box.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Box.png new file mode 100644 index 0000000000..b0df106b87 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Box.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Hermite.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Hermite.png new file mode 100644 index 0000000000..6fd559305b Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Hermite.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos3.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos3.png new file mode 100644 index 0000000000..53c9c9ba16 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos3.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos5.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos5.png new file mode 100644 index 0000000000..4895e620d2 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos5.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos8.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos8.png new file mode 100644 index 0000000000..8f322f8494 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Lanczos8.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_MitchellNetravali.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_MitchellNetravali.png new file mode 100644 index 0000000000..f766126f9b Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_MitchellNetravali.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_NearestNeighbor.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_NearestNeighbor.png new file mode 100644 index 0000000000..f2ebc50c6d Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_NearestNeighbor.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Robidoux.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Robidoux.png new file mode 100644 index 0000000000..a7cddbe078 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Robidoux.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_RobidouxSharp.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_RobidouxSharp.png new file mode 100644 index 0000000000..40d4496657 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_RobidouxSharp.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Spline.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Spline.png new file mode 100644 index 0000000000..49a76b237e Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Spline.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Triangle.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Triangle.png new file mode 100644 index 0000000000..3e621f23f3 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Triangle.png differ diff --git a/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Welch.png b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Welch.png new file mode 100644 index 0000000000..5075b9d972 Binary files /dev/null and b/tests/ImageSharp.Tests/ReferenceOutput/ResizeTests/ImageShouldResize_Rgba32_Calliphora_Welch.png differ diff --git a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs index 2901238856..59c5813ad2 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs @@ -112,6 +112,9 @@ namespace ImageSharp.Tests } } + internal string GetReferenceOutputFileName(string extension = null, string tag = null) + => this.GetTestOutputFileName(extension, tag).Replace("TestOutput", "ReferenceOutput"); + internal void Init(string typeName, string methodName) { this.TestGroupName = typeName; diff --git a/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs index 53986e64a6..1bf90ac7db 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs @@ -57,6 +57,11 @@ var fullRect = new System.Drawing.Rectangle(0, 0, w, h); + if (bmp.PixelFormat != PixelFormat.Format32bppArgb) + { + throw new ArgumentException("FromSystemDrawingBitmap(): pixel format not supported", nameof(bmp)); + } + BitmapData data = bmp.LockBits(fullRect, ImageLockMode.ReadWrite, bmp.PixelFormat); byte* sourcePtrBase = (byte*)data.Scan0; diff --git a/tests/ImageSharp.Tests/TestUtilities/Integration/ReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/Integration/ReferenceDecoder.cs new file mode 100644 index 0000000000..3e905cc071 --- /dev/null +++ b/tests/ImageSharp.Tests/TestUtilities/Integration/ReferenceDecoder.cs @@ -0,0 +1,40 @@ +namespace ImageSharp.Tests.TestUtilities.Integration +{ + using System; + using System.Drawing; + using System.IO; + + using ImageSharp.Formats; + using ImageSharp.PixelFormats; + + public class ReferenceDecoder : IImageDecoder + { + public static ReferenceDecoder Instance { get; } = new ReferenceDecoder(); + + public Image Decode(Configuration configuration, Stream stream, IDecoderOptions options) + where TPixel : struct, IPixel + { + using (var sourceBitmap = new System.Drawing.Bitmap(stream)) + { + if (sourceBitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb) + { + return IntegrationTestUtils.FromSystemDrawingBitmap(sourceBitmap); + } + + using (var convertedBitmap = new System.Drawing.Bitmap( + sourceBitmap.Width, + sourceBitmap.Height, + System.Drawing.Imaging.PixelFormat.Format32bppArgb)) + { + using (var g = Graphics.FromImage(convertedBitmap)) + { + g.DrawImage(sourceBitmap, new PointF(0, 0)); + } + return IntegrationTestUtils.FromSystemDrawingBitmap(convertedBitmap); + } + + + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/Integration/ReferencePngDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/Integration/ReferencePngDecoder.cs deleted file mode 100644 index f2ac69fd4d..0000000000 --- a/tests/ImageSharp.Tests/TestUtilities/Integration/ReferencePngDecoder.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace ImageSharp.Tests.TestUtilities.Integration -{ - using System; - using System.IO; - - using ImageSharp.Formats; - using ImageSharp.PixelFormats; - - public class ReferencePngDecoder : IImageDecoder - { - public static ReferencePngDecoder Instance { get; } = new ReferencePngDecoder(); - - public Image Decode(Configuration configuration, Stream stream, IDecoderOptions options) - where TPixel : struct, IPixel - { - using (var sdBitmap = new System.Drawing.Bitmap(stream)) - { - if (!sdBitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png)) - { - throw new Exception("Reference image should be a Png!"); - } - if (sdBitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb) - { - throw new Exception("Reference image pixel format should be PixelFormat.Format32bppArgb!"); - } - - return IntegrationTestUtils.FromSystemDrawingBitmap(sdBitmap); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index bb97daaa47..e1edfbe8a7 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -7,10 +7,12 @@ namespace ImageSharp.Tests { using System; using System.Collections.Generic; + using System.IO; using System.Linq; using System.Reflection; using ImageSharp.PixelFormats; + using ImageSharp.Tests.TestUtilities.Integration; public static class TestImageExtensions { @@ -57,5 +59,60 @@ namespace ImageSharp.Tests provider.Utility.SaveTestOutputFile(image, extension, tag: tag); return image; } + + public static Image CompareToReferenceOutput( + this Image image, + ITestImageProvider provider, + object settings = null, + string extension = "png", + float imageTheshold = ImageComparer.DefaultImageThreshold, + byte segmentThreshold = ImageComparer.DefaultSegmentThreshold, + int scalingFactor = ImageComparer.DefaultScalingFactor) + where TPixel : struct, IPixel + { + // We are running locally then we want to save it out + string tag = null; + string s = settings as string; + + if (s != null) + { + tag = s; + } + else if (settings != null) + { + Type type = settings.GetType(); + TypeInfo info = type.GetTypeInfo(); + if (info.IsPrimitive || info.IsEnum || type == typeof(decimal)) + { + tag = settings.ToString(); + } + else + { + IEnumerable properties = settings.GetType().GetRuntimeProperties(); + + tag = string.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}")); + } + } + + string referenceOutputFile = provider.Utility.GetReferenceOutputFileName(extension, tag); + + if (!(bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCi) && isCi)) + { + provider.Utility.SaveTestOutputFile(image, extension, tag: tag); + } + + if (!File.Exists(referenceOutputFile)) + { + throw new Exception("Reference output file missing: " + referenceOutputFile); + } + + using (Image referenceImage = Image.Load(referenceOutputFile, ReferenceDecoder.Instance)) + { + ImageComparer.VerifySimilarity(referenceImage, image, imageTheshold, segmentThreshold, scalingFactor); + } + + + return image; + } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs index d1ceef03ba..54dbd682df 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs @@ -52,7 +52,7 @@ namespace ImageSharp.Tests where TPixel : struct, IPixel { string path = TestFile.GetPath(TestImages.Png.Splash); - using (Image image = Image.Load(path, ReferencePngDecoder.Instance)) + using (Image image = Image.Load(path, ReferenceDecoder.Instance)) { image.DebugSave(dummyProvider); }