diff --git a/tests/ImageSharp.Tests/ImageComparer.cs b/tests/ImageSharp.Tests/ImageComparer.cs
index 6cd80e9e8..4a37c6c45 100644
--- a/tests/ImageSharp.Tests/ImageComparer.cs
+++ b/tests/ImageSharp.Tests/ImageComparer.cs
@@ -72,9 +72,13 @@ 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(Image expected, Image actual, float imageTheshold = DefaultImageThreshold, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor)
- where TPixelA : struct, IPixel
- where TPixelB : struct, IPixel
+ public static void CheckSimilarity(
+ Image expected,
+ Image actual,
+ float imageTheshold = DefaultImageThreshold,
+ byte segmentThreshold = DefaultSegmentThreshold,
+ int scalingFactor = DefaultScalingFactor)
+ where TPixelA : struct, IPixel where TPixelB : struct, IPixel
{
float percentage = expected.PercentageDifference(actual, segmentThreshold, scalingFactor);
diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj
index b0429d9ed..aded62b8f 100644
--- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj
+++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj
@@ -10,6 +10,7 @@
+
diff --git a/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs
new file mode 100644
index 000000000..f4a125733
--- /dev/null
+++ b/tests/ImageSharp.Tests/TestUtilities/Integration/IntegrationTestUtils.cs
@@ -0,0 +1,65 @@
+namespace ImageSharp.Tests.TestUtilities.Integration
+{
+ using System;
+ using System.Drawing.Imaging;
+
+ using ImageSharp.Memory;
+ using ImageSharp.PixelFormats;
+
+ public static class IntegrationTestUtils
+ {
+ // TODO: It would be nice to have this method in PixelOperations
+ private static void ToArgb32(Span source, Span dest)
+ where TPixel : struct, IPixel
+ {
+ int length = source.Length;
+ Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
+
+ using (var rgbaBuffer = new Buffer(length))
+ {
+ PixelOperations.Instance.ToRgba32(source, rgbaBuffer, length);
+
+ for (int i = 0; i < length; i++)
+ {
+ ref Rgba32 s = ref rgbaBuffer[i];
+ ref Argb32 d = ref dest[i];
+
+ d.PackFromRgba32(s);
+ }
+ }
+ }
+
+ internal static unsafe System.Drawing.Bitmap ToSystemDrawingBitmap(Image image)
+ where TPixel : struct, IPixel
+ {
+ int w = image.Width;
+ int h = image.Height;
+
+ var resultBitmap = new System.Drawing.Bitmap(w, h, PixelFormat.Format32bppArgb);
+ var fullRect = new System.Drawing.Rectangle(0, 0, w, h);
+ BitmapData data = resultBitmap.LockBits(fullRect, ImageLockMode.ReadWrite, resultBitmap.PixelFormat);
+ byte* destPtrBase = (byte*)data.Scan0;
+
+ long destRowByteCount= data.Stride;
+ long sourceRowByteCount = w * sizeof(Argb32);
+
+ using (var workBuffer = new Buffer(w))
+ {
+ var sourcePtr = (Argb32*) workBuffer.Pin();
+
+ for (int y = 0; y < h; y++)
+ {
+ Span row = image.GetRowSpan(y);
+ ToArgb32(row, workBuffer);
+ byte* destPtr = destPtrBase + data.Stride * y;
+
+ Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);
+ }
+ }
+
+ resultBitmap.UnlockBits(data);
+
+ return resultBitmap;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/TestUtilities/Integration/ReferenceEncoder.cs b/tests/ImageSharp.Tests/TestUtilities/Integration/ReferenceEncoder.cs
new file mode 100644
index 000000000..60c21971b
--- /dev/null
+++ b/tests/ImageSharp.Tests/TestUtilities/Integration/ReferenceEncoder.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ImageSharp.Tests.TestUtilities.Integration
+{
+ using System.IO;
+
+ using ImageSharp.Formats;
+ using ImageSharp.PixelFormats;
+
+ public class ReferenceEncoder : IImageEncoder
+ {
+ public void Encode(Image image, Stream stream, IEncoderOptions options)
+ where TPixel : struct, IPixel
+ {
+ System.Drawing.Bitmap sdBitmap = IntegrationTestUtils.ToSystemDrawingBitmap(image);
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs
new file mode 100644
index 000000000..abb7f1262
--- /dev/null
+++ b/tests/ImageSharp.Tests/TestUtilities/Tests/IntegrationTestUtilsTests.cs
@@ -0,0 +1,33 @@
+namespace ImageSharp.Tests
+{
+ using ImageSharp.PixelFormats;
+ using ImageSharp.Tests.TestUtilities.Integration;
+
+ using Xunit;
+ using Xunit.Abstractions;
+
+ public class IntegrationTestUtilsTests
+ {
+ private ITestOutputHelper Output { get; }
+
+ public IntegrationTestUtilsTests(ITestOutputHelper output)
+ {
+ this.Output = output;
+ }
+
+ [Theory]
+ [WithTestPatternImages(20, 20, PixelTypes.Rgba32 | PixelTypes.Bgra32)]
+ public void ToSystemDrawingBitmap(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ using (Image image = provider.GetImage())
+ {
+ using (System.Drawing.Bitmap sdBitmap = IntegrationTestUtils.ToSystemDrawingBitmap(image))
+ {
+ string fileName = provider.Utility.GetTestOutputFileName("png");
+ sdBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file