From 11738c1e2f3c91507312af0a71f0fdc757f7e6ec Mon Sep 17 00:00:00 2001 From: Stefan Seeland <168659+stesee@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:17:52 +0200 Subject: [PATCH 1/3] Add support for all SixLabors.ImageSharp.PixelFormats Marked ConvertRgba32ToRgb24 obsolete --- ImageSharpCompare/ImageSharpCompare.cs | 16 ++--- ImageSharpCompare/ImageSharpCompare.csproj | 2 +- .../ImageSharpCompareTest.cs | 65 +++++++++++++++++++ .../ImageSharpCompareTestNunit.csproj | 8 +-- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/ImageSharpCompare/ImageSharpCompare.cs b/ImageSharpCompare/ImageSharpCompare.cs index 9c1477c..c926894 100644 --- a/ImageSharpCompare/ImageSharpCompare.cs +++ b/ImageSharpCompare/ImageSharpCompare.cs @@ -350,7 +350,7 @@ public static ICompareResult CalcDiff(Image actual, Image expected var g = Math.Abs(expectedPixel.G - actualPixel.G); var b = Math.Abs(expectedPixel.B - actualPixel.B); var sum = r + g + b; - absoluteError = absoluteError + (sum > pixelColorShiftTolerance ? sum : 0); + absoluteError += (sum > pixelColorShiftTolerance ? sum : 0); pixelErrorCount += (sum > pixelColorShiftTolerance) ? 1 : 0; } } @@ -477,7 +477,7 @@ public static ICompareResult CalcDiff(Image actual, Image expected error += b; } - absoluteError = absoluteError + (error > pixelColorShiftTolerance ? error : 0); + absoluteError += (error > pixelColorShiftTolerance ? error : 0); pixelErrorCount += error > pixelColorShiftTolerance ? 1 : 0; } } @@ -752,19 +752,17 @@ private static Image ToRgb24Image(Image actual, out bool ownsImage) return actualPixelAccessibleImage; } - if (actual is Image imageRgba32) - { - ownsImage = true; - return ConvertRgba32ToRgb24(imageRgba32); - } - - throw new NotImplementedException($"Pixel type {actual.PixelType} is not supported to be compared."); + ownsImage = true; + return actual.CloneAs(); } /// /// Converts a Rgba32 Image to Rgb24 one /// /// +#pragma warning disable S1133 // Give the consumer of the public method some time to migrate + [Obsolete("use 'imageRgba32..CloneAs()' instead")] +#pragma warning restore S1133 public static Image ConvertRgba32ToRgb24(Image imageRgba32) { ArgumentNullException.ThrowIfNull(imageRgba32); diff --git a/ImageSharpCompare/ImageSharpCompare.csproj b/ImageSharpCompare/ImageSharpCompare.csproj index 7aa21f5..686acd7 100644 --- a/ImageSharpCompare/ImageSharpCompare.csproj +++ b/ImageSharpCompare/ImageSharpCompare.csproj @@ -46,7 +46,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs b/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs index 32da56e..81a5982 100644 --- a/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs +++ b/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs @@ -125,6 +125,38 @@ public void ShouldVerifyThatImageSharpImagesAreEqual(string pathActual, string p AssertDisposeBehavior(expected); } + [Test] + [TestCase(jpg0Rgb24, jpg0Rgb24)] + [TestCase(png0Rgba32, png0Rgba32)] + public void ShouldVerifyThatImageSharpImagesAreEqualBrga(string pathActual, string pathExpected) + { + var absolutePathActual = Path.Combine(AppContext.BaseDirectory, pathActual); + var absolutePathExpected = Path.Combine(AppContext.BaseDirectory, pathExpected); + + using var actual = Image.Load(absolutePathActual); + using var expected = Image.Load(absolutePathExpected); + + Assert.That(ImageSharpCompare.ImagesAreEqual(actual, expected), Is.True); + AssertDisposeBehavior(actual); + AssertDisposeBehavior(expected); + } + + [Test] + [TestCase(jpg0Rgb24, jpg0Rgb24)] + [TestCase(png0Rgba32, png0Rgba32)] + public void ShouldVerifyThatImageSharpImagesAreEqualBgra5551(string pathActual, string pathExpected) + { + var absolutePathActual = Path.Combine(AppContext.BaseDirectory, pathActual); + var absolutePathExpected = Path.Combine(AppContext.BaseDirectory, pathExpected); + + using var actual = Image.Load(absolutePathActual); + using var expected = Image.Load(absolutePathExpected); + + Assert.That(ImageSharpCompare.ImagesAreEqual(actual, expected), Is.True); + AssertDisposeBehavior(actual); + AssertDisposeBehavior(expected); + } + [Test] [TestCase(jpg0Rgb24, png0Rgba32, 384538, 2.3789191061839596d, 140855, 87.139021553537404d, null, 0)] [TestCase(jpg0Rgb24, png0Rgba32, 384538, 2.3789191061839596d, 140855, 87.139021553537404d, ResizeOption.DontResize, 0)] @@ -260,6 +292,39 @@ public void ShouldCalcDiffMaskImageSharpAndUseOutcome(string pathPic1, string pa AssertDisposeBehavior(differenceMaskPic); } + [TestCase(png0Rgba32, png1Rgba32, 0, 0, 0, 0, ResizeOption.DontResize)] + [TestCase(jpg0Rgb24, jpg1Rgb24, 0, 0, 0, 0, ResizeOption.DontResize)] + [TestCase(jpg0Rgb24, jpg1Rgb24, 0, 0, 0, 0, ResizeOption.Resize)] + [TestCase(pngBlack2x2px, pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize)] + public void ShouldCalcDiffMaskImageHalfSingleSharpAndUseOutcome(string pathPic1, string pathPic2, int expectedMeanError, int expectedAbsoluteError, int expectedPixelErrorCount, double expectedPixelErrorPercentage, ResizeOption resizeOption) + { + var absolutePathPic1 = Path.Combine(AppContext.BaseDirectory, pathPic1); + var absolutePathPic2 = Path.Combine(AppContext.BaseDirectory, pathPic2); + var differenceMaskPicPath = Path.GetTempFileName() + "differenceMask.png"; + + using var absolutePic1 = Image.Load(absolutePathPic1); + using var absolutePic2 = Image.Load(absolutePathPic2); + + using (var fileStreamDifferenceMask = File.Create(differenceMaskPicPath)) + using (var maskImage = ImageSharpCompare.CalcDiffMaskImage(absolutePic1, absolutePic2, resizeOption)) + { + ImageExtensions.SaveAsPng(maskImage, fileStreamDifferenceMask); + } + + using var differenceMaskPic = Image.Load(differenceMaskPicPath); + var maskedDiff = ImageSharpCompare.CalcDiff(absolutePic1, absolutePic2, differenceMaskPic, resizeOption); + File.Delete(differenceMaskPicPath); + + Assert.That(maskedDiff.AbsoluteError, Is.EqualTo(expectedAbsoluteError), "AbsoluteError"); + Assert.That(maskedDiff.MeanError, Is.EqualTo(expectedMeanError), "MeanError"); + Assert.That(maskedDiff.PixelErrorCount, Is.EqualTo(expectedPixelErrorCount), "PixelErrorCount"); + Assert.That(maskedDiff.PixelErrorPercentage, Is.EqualTo(expectedPixelErrorPercentage), "PixelErrorPercentage"); + + AssertDisposeBehavior(absolutePic1); + AssertDisposeBehavior(absolutePic2); + AssertDisposeBehavior(differenceMaskPic); + } + [TestCase(pngWhite2x2px, pngBlack2x2px, pngTransparent2x2px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)] [TestCase(pngWhite2x2px, pngBlack2x2px, pngBlack4x4px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)] [TestCase(pngBlack2x2px, pngBlack2x2px, pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize, 0)] diff --git a/ImageSharpCompareTestNunit/ImageSharpCompareTestNunit.csproj b/ImageSharpCompareTestNunit/ImageSharpCompareTestNunit.csproj index 3971973..645d465 100644 --- a/ImageSharpCompareTestNunit/ImageSharpCompareTestNunit.csproj +++ b/ImageSharpCompareTestNunit/ImageSharpCompareTestNunit.csproj @@ -8,12 +8,12 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -21,7 +21,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From 584175a490c9a0f63291bcffac624842b3804b3a Mon Sep 17 00:00:00 2001 From: Stefan Seeland <168659+stesee@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:24:37 +0200 Subject: [PATCH 2/3] Update ImageSharpCompareTest.cs --- ImageSharpCompareTestNunit/ImageSharpCompareTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs b/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs index 81a5982..88d97ba 100644 --- a/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs +++ b/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs @@ -296,13 +296,13 @@ public void ShouldCalcDiffMaskImageSharpAndUseOutcome(string pathPic1, string pa [TestCase(jpg0Rgb24, jpg1Rgb24, 0, 0, 0, 0, ResizeOption.DontResize)] [TestCase(jpg0Rgb24, jpg1Rgb24, 0, 0, 0, 0, ResizeOption.Resize)] [TestCase(pngBlack2x2px, pngBlack4x4px, 0, 0, 0, 0, ResizeOption.Resize)] - public void ShouldCalcDiffMaskImageHalfSingleSharpAndUseOutcome(string pathPic1, string pathPic2, int expectedMeanError, int expectedAbsoluteError, int expectedPixelErrorCount, double expectedPixelErrorPercentage, ResizeOption resizeOption) + public void ShouldCalcDiffMaskImageHalfSingleHalfVector2AndUseOutcome(string pathPic1, string pathPic2, int expectedMeanError, int expectedAbsoluteError, int expectedPixelErrorCount, double expectedPixelErrorPercentage, ResizeOption resizeOption) { var absolutePathPic1 = Path.Combine(AppContext.BaseDirectory, pathPic1); var absolutePathPic2 = Path.Combine(AppContext.BaseDirectory, pathPic2); var differenceMaskPicPath = Path.GetTempFileName() + "differenceMask.png"; - using var absolutePic1 = Image.Load(absolutePathPic1); + using var absolutePic1 = Image.Load(absolutePathPic1); using var absolutePic2 = Image.Load(absolutePathPic2); using (var fileStreamDifferenceMask = File.Create(differenceMaskPicPath)) From 731ea0d9706dce1d9197eed6bd0f5bd0ddb53f7d Mon Sep 17 00:00:00 2001 From: Stefan Seeland <168659+stesee@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:57:35 +0200 Subject: [PATCH 3/3] Moved ToRgb24Image into new class --- ImageSharpCompare/ImageSharpCompare.cs | 36 ++++------- .../ImageSharpPixelTypeConverter.cs | 31 ++++++++++ .../AssertDisposeBehavior.cs | 28 +++++++++ .../ImageSharpCompareTest.cs | 60 +++++++------------ .../ImageSharpPixelTypeConverterTests.cs | 46 ++++++++++++++ 5 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 ImageSharpCompare/ImageSharpPixelTypeConverter.cs create mode 100644 ImageSharpCompareTestNunit/AssertDisposeBehavior.cs create mode 100644 ImageSharpCompareTestNunit/ImageSharpPixelTypeConverterTests.cs diff --git a/ImageSharpCompare/ImageSharpCompare.cs b/ImageSharpCompare/ImageSharpCompare.cs index c926894..67b3723 100644 --- a/ImageSharpCompare/ImageSharpCompare.cs +++ b/ImageSharpCompare/ImageSharpCompare.cs @@ -139,8 +139,8 @@ public static bool ImagesAreEqual(Image actual, Image expected, ResizeOption res Image? expectedPixelAccusableImage = null; try { - actualPixelAccessibleImage = ToRgb24Image(actual, out ownsActual); - expectedPixelAccusableImage = ToRgb24Image(expected, out ownsExpected); + actualPixelAccessibleImage = ImageSharpPixelTypeConverter.ToRgb24Image(actual, out ownsActual); + expectedPixelAccusableImage = ImageSharpPixelTypeConverter.ToRgb24Image(expected, out ownsExpected); return ImagesAreEqual(actualPixelAccessibleImage, expectedPixelAccusableImage, resizeOption); } @@ -286,8 +286,8 @@ public static ICompareResult CalcDiff(Image actual, Image expected, ResizeOption try { - actualRgb24 = ToRgb24Image(actual, out ownsActual); - expectedRgb24 = ToRgb24Image(expected, out ownsExpected); + actualRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(actual, out ownsActual); + expectedRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(expected, out ownsExpected); return CalcDiff(actualRgb24, expectedRgb24, resizeOption, pixelColorShiftTolerance); } @@ -386,9 +386,9 @@ public static ICompareResult CalcDiff(Image actual, Image expected, Image maskIm try { - actualRgb24 = ToRgb24Image(actual, out ownsActual); - expectedRgb24 = ToRgb24Image(expected, out ownsExpected); - maskImageRgb24 = ToRgb24Image(maskImage, out ownsMask); + actualRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(actual, out ownsActual); + expectedRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(expected, out ownsExpected); + maskImageRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(maskImage, out ownsMask); return CalcDiff(actualRgb24, expectedRgb24, maskImageRgb24, resizeOption, pixelColorShiftTolerance); } @@ -571,8 +571,8 @@ public static Image CalcDiffMaskImage(Image actual, Image expected, ResizeOption try { - actualRgb24 = ToRgb24Image(actual, out ownsActual); - expectedRgb24 = ToRgb24Image(expected, out ownsExpected); + actualRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(actual, out ownsActual); + expectedRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(expected, out ownsExpected); return CalcDiffMaskImage(actualRgb24, expectedRgb24, resizeOption, pixelColorShiftTolerance); } @@ -612,9 +612,9 @@ public static Image CalcDiffMaskImage(Image actual, Image expected, Image mask, try { - actualRgb24 = ToRgb24Image(actual, out ownsActual); - expectedRgb24 = ToRgb24Image(expected, out ownsExpected); - maskRgb24 = ToRgb24Image(mask, out ownsMask); + actualRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(actual, out ownsActual); + expectedRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(expected, out ownsExpected); + maskRgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(mask, out ownsMask); return CalcDiffMaskImage(actualRgb24, expectedRgb24, maskRgb24, resizeOption, pixelColorShiftTolerance); } @@ -744,18 +744,6 @@ public static Image CalcDiffMaskImage(Image actual, Image expected } } - private static Image ToRgb24Image(Image actual, out bool ownsImage) - { - if (actual is Image actualPixelAccessibleImage) - { - ownsImage = false; - return actualPixelAccessibleImage; - } - - ownsImage = true; - return actual.CloneAs(); - } - /// /// Converts a Rgba32 Image to Rgb24 one /// diff --git a/ImageSharpCompare/ImageSharpPixelTypeConverter.cs b/ImageSharpCompare/ImageSharpPixelTypeConverter.cs new file mode 100644 index 0000000..48ca8d5 --- /dev/null +++ b/ImageSharpCompare/ImageSharpPixelTypeConverter.cs @@ -0,0 +1,31 @@ +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using System; + +namespace Codeuctivity.ImageSharpCompare +{ + /// + /// Provides functionality to convert an ImageSharp image of any pixel type to an ImageSharp image with Rgb24 pixel type. + /// + public static class ImageSharpPixelTypeConverter + { + /// + /// Converts an Image with any pixel type to Rgb24 + /// + /// + /// Use this to dispose cloned instances + public static Image ToRgb24Image(Image image, out bool isClonedInstance) + { + ArgumentNullException.ThrowIfNull(image); + + if (image is Image actualPixelAccessibleImage) + { + isClonedInstance = false; + return actualPixelAccessibleImage; + } + + isClonedInstance = true; + return image.CloneAs(); + } + } +} \ No newline at end of file diff --git a/ImageSharpCompareTestNunit/AssertDisposeBehavior.cs b/ImageSharpCompareTestNunit/AssertDisposeBehavior.cs new file mode 100644 index 0000000..8d71f58 --- /dev/null +++ b/ImageSharpCompareTestNunit/AssertDisposeBehavior.cs @@ -0,0 +1,28 @@ +using NUnit.Framework; +using SixLabors.ImageSharp; +using System; +using System.Reflection; + +namespace ImageSharpCompareTestNunit +{ + internal static class AssertDisposeBehavior + { + + internal static void AssertThatImageIsDisposed(Image image, bool expectedDisposeState = false) + { + const string imageSharpPrivateFieldNameIsDisposed = "isDisposed"; + var isDisposed = (bool?)GetInstanceField(image, imageSharpPrivateFieldNameIsDisposed); + Assert.That(isDisposed, Is.EqualTo(expectedDisposeState)); + image.Dispose(); + isDisposed = (bool?)GetInstanceField(image, imageSharpPrivateFieldNameIsDisposed); + Assert.That(isDisposed, Is.True); + } + + private static object? GetInstanceField(T instance, string fieldName) + { + var bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; + var field = typeof(T).GetField(fieldName, bindFlags); + return field == null ? throw new ArgumentNullException(fieldName) : field.GetValue(instance); + } + } +} \ No newline at end of file diff --git a/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs b/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs index 88d97ba..26b59a5 100644 --- a/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs +++ b/ImageSharpCompareTestNunit/ImageSharpCompareTest.cs @@ -4,7 +4,6 @@ using SixLabors.ImageSharp.PixelFormats; using System; using System.IO; -using System.Reflection; namespace ImageSharpCompareTestNunit { @@ -121,8 +120,8 @@ public void ShouldVerifyThatImageSharpImagesAreEqual(string pathActual, string p using var expected = Image.Load(absolutePathExpected); Assert.That(ImageSharpCompare.ImagesAreEqual(actual, expected), Is.True); - AssertDisposeBehavior(actual); - AssertDisposeBehavior(expected); + AssertDisposeBehavior.AssertThatImageIsDisposed(actual); + AssertDisposeBehavior.AssertThatImageIsDisposed(expected); } [Test] @@ -137,8 +136,8 @@ public void ShouldVerifyThatImageSharpImagesAreEqualBrga(string pathActual, stri using var expected = Image.Load(absolutePathExpected); Assert.That(ImageSharpCompare.ImagesAreEqual(actual, expected), Is.True); - AssertDisposeBehavior(actual); - AssertDisposeBehavior(expected); + AssertDisposeBehavior.AssertThatImageIsDisposed(actual); + AssertDisposeBehavior.AssertThatImageIsDisposed(expected); } [Test] @@ -153,8 +152,8 @@ public void ShouldVerifyThatImageSharpImagesAreEqualBgra5551(string pathActual, using var expected = Image.Load(absolutePathExpected); Assert.That(ImageSharpCompare.ImagesAreEqual(actual, expected), Is.True); - AssertDisposeBehavior(actual); - AssertDisposeBehavior(expected); + AssertDisposeBehavior.AssertThatImageIsDisposed(actual); + AssertDisposeBehavior.AssertThatImageIsDisposed(expected); } [Test] @@ -286,10 +285,10 @@ public void ShouldCalcDiffMaskImageSharpAndUseOutcome(string pathPic1, string pa Assert.That(maskedDiff.MeanError, Is.EqualTo(expectedMeanError), "MeanError"); Assert.That(maskedDiff.PixelErrorCount, Is.EqualTo(expectedPixelErrorCount), "PixelErrorCount"); Assert.That(maskedDiff.PixelErrorPercentage, Is.EqualTo(expectedPixelErrorPercentage), "PixelErrorPercentage"); - - AssertDisposeBehavior(absolutePic1); - AssertDisposeBehavior(absolutePic2); - AssertDisposeBehavior(differenceMaskPic); + AssertDisposeBehavior. + AssertThatImageIsDisposed(absolutePic1); + AssertDisposeBehavior.AssertThatImageIsDisposed(absolutePic2); + AssertDisposeBehavior.AssertThatImageIsDisposed(differenceMaskPic); } [TestCase(png0Rgba32, png1Rgba32, 0, 0, 0, 0, ResizeOption.DontResize)] @@ -319,10 +318,10 @@ public void ShouldCalcDiffMaskImageHalfSingleHalfVector2AndUseOutcome(string pat Assert.That(maskedDiff.MeanError, Is.EqualTo(expectedMeanError), "MeanError"); Assert.That(maskedDiff.PixelErrorCount, Is.EqualTo(expectedPixelErrorCount), "PixelErrorCount"); Assert.That(maskedDiff.PixelErrorPercentage, Is.EqualTo(expectedPixelErrorPercentage), "PixelErrorPercentage"); - - AssertDisposeBehavior(absolutePic1); - AssertDisposeBehavior(absolutePic2); - AssertDisposeBehavior(differenceMaskPic); + AssertDisposeBehavior. + AssertThatImageIsDisposed(absolutePic1); + AssertDisposeBehavior.AssertThatImageIsDisposed(absolutePic2); + AssertDisposeBehavior.AssertThatImageIsDisposed(differenceMaskPic); } [TestCase(pngWhite2x2px, pngBlack2x2px, pngTransparent2x2px, 765, 12240, 16, 100d, ResizeOption.Resize, 0)] @@ -346,10 +345,10 @@ public void ShouldUseDiffMask(string pathPic1, string pathPic2, string pathPic3, Assert.That(maskedDiff.AbsoluteError, Is.EqualTo(expectedAbsoluteError), "AbsoluteError"); Assert.That(maskedDiff.PixelErrorCount, Is.EqualTo(expectedPixelErrorCount), "PixelErrorCount"); Assert.That(maskedDiff.PixelErrorPercentage, Is.EqualTo(expectedPixelErrorPercentage), "PixelErrorPercentage"); - - AssertDisposeBehavior(pic1); - AssertDisposeBehavior(pic2); - AssertDisposeBehavior(maskPic); + AssertDisposeBehavior. + AssertThatImageIsDisposed(pic1); + AssertDisposeBehavior.AssertThatImageIsDisposed(pic2); + AssertDisposeBehavior.AssertThatImageIsDisposed(maskPic); } [TestCase(pngBlack2x2px, pngBlack2x2px, pngBlack4x4px)] @@ -367,28 +366,13 @@ public void ShouldThrowUsingInvalidImageDimensionsDiffMask(string pathPic1, stri var exception = Assert.Throws(() => ImageSharpCompare.CalcDiff(pic1, pic2, maskPic, ResizeOption.DontResize)); Assert.That(exception?.Message, Is.EqualTo("Size of images differ.")); - - AssertDisposeBehavior(pic1); - AssertDisposeBehavior(pic2); - AssertDisposeBehavior(maskPic); + AssertDisposeBehavior. + AssertThatImageIsDisposed(pic1); + AssertDisposeBehavior.AssertThatImageIsDisposed(pic2); + AssertDisposeBehavior.AssertThatImageIsDisposed(maskPic); } - private static void AssertDisposeBehavior(Image image) - { - const string imageSharpPrivateFieldNameIsDisposed = "isDisposed"; - var isDisposed = (bool?)GetInstanceField(image, imageSharpPrivateFieldNameIsDisposed); - Assert.That(isDisposed, Is.False); - image.Dispose(); - isDisposed = (bool?)GetInstanceField(image, imageSharpPrivateFieldNameIsDisposed); - Assert.That(isDisposed, Is.True); - } - private static object? GetInstanceField(T instance, string fieldName) - { - var bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; - var field = typeof(T).GetField(fieldName, bindFlags); - return field == null ? throw new ArgumentNullException(fieldName) : field.GetValue(instance); - } [TestCase(png0Rgba32, png1Rgba32, 0, 0, 0, 0)] public void DiffMaskSteams(string pathPic1, string pathPic2, int expectedMeanError, int expectedAbsoluteError, int expectedPixelErrorCount, double expectedPixelErrorPercentage) diff --git a/ImageSharpCompareTestNunit/ImageSharpPixelTypeConverterTests.cs b/ImageSharpCompareTestNunit/ImageSharpPixelTypeConverterTests.cs new file mode 100644 index 0000000..740ac92 --- /dev/null +++ b/ImageSharpCompareTestNunit/ImageSharpPixelTypeConverterTests.cs @@ -0,0 +1,46 @@ +using Codeuctivity.ImageSharpCompare; +using NUnit.Framework; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using System; +using System.IO; + +namespace ImageSharpCompareTestNunit +{ + public class ImageSharpPixelTypeConverterTests + { + private const string pngBlack2x2px = "../../../TestData/Black.png"; + + [Test] + public void ShouldConvertToRgb24() + { + var absolutePathActual = Path.Combine(AppContext.BaseDirectory, pngBlack2x2px); + + var image = Image.Load(absolutePathActual); + + var rgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(image, out var isClonedInstance); + + Assert.That(isClonedInstance, Is.False); + Assert.That(rgb24.PixelType.BitsPerPixel, Is.EqualTo(24)); + + image.Dispose(); + AssertDisposeBehavior.AssertThatImageIsDisposed(rgb24, true); + } + + [Test] + public void ShouldConvertAnyPixelTypeToRgb24() + { + var absolutePathActual = Path.Combine(AppContext.BaseDirectory, pngBlack2x2px); + + var image = Image.Load(absolutePathActual); + + var rgb24 = ImageSharpPixelTypeConverter.ToRgb24Image(image, out var isClonedInstance); + + Assert.That(isClonedInstance, Is.True); + Assert.That(rgb24.PixelType.BitsPerPixel, Is.EqualTo(24)); + + image.Dispose(); + AssertDisposeBehavior.AssertThatImageIsDisposed(rgb24); + } + } +}