From 6ab7954bfd30d9ce5e383ab8c58a9b9dae47ff49 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 22 Feb 2018 14:46:07 +0100 Subject: [PATCH 1/3] MakeOpaque + fixing BmpEncoderTests --- .../Processing/ColorMatrix/Opacity.cs | 4 +- .../Formats/Bmp/BmpEncoderTests.cs | 6 ++- .../Formats/Jpg/JpegEncoderTests.cs | 2 +- .../Formats/Png/PngEncoderTests.cs | 21 ++++----- .../TestUtilities/TestImageExtensions.cs | 45 +++++++++++++++---- .../Tests/ReferenceCodecTests.cs | 6 +-- 6 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/ImageSharp/Processing/ColorMatrix/Opacity.cs b/src/ImageSharp/Processing/ColorMatrix/Opacity.cs index b310b4b91..b59c06890 100644 --- a/src/ImageSharp/Processing/ColorMatrix/Opacity.cs +++ b/src/ImageSharp/Processing/ColorMatrix/Opacity.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp public static partial class ImageExtensions { /// - /// Alters the alpha component of the image. + /// Multiplies the alpha component of the image. /// /// The pixel format. /// The image this method extends. @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp => source.ApplyProcessor(new OpacityProcessor(amount)); /// - /// Alters the alpha component of the image. + /// Multiplies the alpha component of the image. /// /// The pixel format. /// The image this method extends. diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs index b1eea79d8..362df2be6 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs @@ -51,13 +51,15 @@ namespace SixLabors.ImageSharp.Tests TestBmpEncoderCore(provider, bitsPerPixel); } + + private static void TestBmpEncoderCore(TestImageProvider provider, BmpBitsPerPixel bitsPerPixel) where TPixel : struct, IPixel - { + { using (Image image = provider.GetImage()) { // there is no alpha in bmp! - image.Mutate(c => c.Opacity(1)); + image.Mutate(c => c.MakeOpaque()); var encoder = new BmpEncoder { BitsPerPixel = bitsPerPixel }; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 8610356b5..10657ea78 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using (Image image = provider.GetImage()) { // There is no alpha in Jpeg! - image.Mutate(c => c.Opacity(1)); + image.Mutate(c => c.MakeOpaque()); var encoder = new JpegEncoder() { diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs index 28f156279..c4f9b0deb 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -123,26 +123,27 @@ namespace SixLabors.ImageSharp.Tests { if (!HasAlpha(pngColorType)) { - image.Mutate(c => c.Opacity(1)); + image.Mutate(c => c.MakeOpaque()); } var encoder = new PngEncoder { PngColorType = pngColorType, CompressionLevel = compressionLevel}; - string pngColorTypeInfo = appendPixelType ? pngColorType.ToString() : ""; + string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : ""; string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : ""; string debugInfo = $"{pngColorTypeInfo}{compressionLevelInfo}"; - string referenceInfo = $"{pngColorTypeInfo}"; - + // Does DebugSave & load reference CompareToReferenceInput(): - string path = ((ITestImageProvider)provider).Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); + string actualOutputFile = ((ITestImageProvider)provider).Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); - IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(path); - string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", referenceInfo, appendPixelType); + IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); - using (var encodedImage = Image.Load(referenceOutputFile, referenceDecoder)) + using (var actualImage = Image.Load(actualOutputFile, referenceDecoder)) { - ImageComparer comparer = pngColorType== PngColorType.Palette ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder) : ImageComparer.Exact; - comparer.CompareImagesOrFrames(image, encodedImage); + ImageComparer comparer = pngColorType == PngColorType.Palette + ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder) + : ImageComparer.Exact; + + comparer.VerifySimilarity(image, actualImage); } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 33dbc911e..6f15cf439 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -22,6 +22,38 @@ namespace SixLabors.ImageSharp.Tests public static class TestImageExtensions { + /// + /// TODO: This should be a common processing method! The image.Opacity(val) multiplies the alpha channel! + /// + /// + /// + public static void MakeOpaque(this IImageProcessingContext ctx) + where TPixel : struct, IPixel + { + ctx.Apply( + img => + { + using (var temp = new Buffer2D(img.Width, img.Height)) + { + Span tempSpan = temp.Span; + foreach (ImageFrame frame in img.Frames) + { + Span pixelSpan = frame.GetPixelSpan(); + + PixelOperations.Instance.ToVector4(pixelSpan, tempSpan, pixelSpan.Length); + + for (int i = 0; i < tempSpan.Length; i++) + { + ref Vector4 v = ref tempSpan[i]; + v.W = 1.0f; + } + + PixelOperations.Instance.PackFromVector4(tempSpan, pixelSpan, pixelSpan.Length); + } + } + }); + } + /// /// Saves the image only when not running in the CI server. /// @@ -357,18 +389,13 @@ namespace SixLabors.ImageSharp.Tests ) where TPixel : struct, IPixel { + string actualOutputFile = provider.Utility.SaveTestOutputFile(image, extension, encoder, testOutputDetails, appendPixelTypeToFileName); + IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); - provider.Utility.SaveTestOutputFile(image, extension, encoder, testOutputDetails, appendPixelTypeToFileName); - - referenceImageExtension = referenceImageExtension ?? extension; - string referenceOutputFile = provider.Utility.GetReferenceOutputFileName(referenceImageExtension, testOutputDetails, appendPixelTypeToFileName); - - IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(referenceOutputFile); - - using (var encodedImage = Image.Load(referenceOutputFile, referenceDecoder)) + using (var actualImage = Image.Load(actualOutputFile, referenceDecoder)) { ImageComparer comparer = customComparer ?? ImageComparer.Exact; - comparer.CompareImagesOrFrames(image, encodedImage); + comparer.VerifySimilarity(actualImage, image); } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs index dde34fcc4..c67e4e06b 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Tests { if (pngColorType != PngColorType.RgbWithAlpha) { - sourceImage.Mutate(c => c.Opacity(1)); + sourceImage.Mutate(c => c.MakeOpaque()); } var encoder = new PngEncoder() { PngColorType = pngColorType }; @@ -93,12 +93,12 @@ namespace SixLabors.ImageSharp.Tests using (Image original = provider.GetImage()) { - original.Mutate(c => c.Opacity(1)); + original.Mutate(c => c.MakeOpaque()); using (var sdBitmap = new System.Drawing.Bitmap(path)) { using (Image resaved = SystemDrawingBridge.FromFromRgb24SystemDrawingBitmap(sdBitmap)) { - resaved.Mutate(c => c.Opacity(1)); + resaved.Mutate(c => c.MakeOpaque()); ImageComparer comparer = ImageComparer.Exact; comparer.VerifySimilarity(original, resaved); } From 9dc3261310527fc277a3864f0eedeca7372ea9aa Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 22 Feb 2018 15:13:08 +0100 Subject: [PATCH 2/3] fixed PngEncoderTests --- .../Formats/Png/PngEncoderTests.cs | 47 ++++++++----------- tests/Images/External | 2 +- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs index c4f9b0deb..0010bb41d 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests public void IsNotBoundToSinglePixelType(TestImageProvider provider, PngColorType pngColorType) where TPixel : struct, IPixel { - TestPngEncoderCore(provider, pngColorType, appendPixelType: true); + TestPngEncoderCore(provider, pngColorType, appendPixelType: true, appendPngColorType: true); } [Theory] @@ -78,33 +78,13 @@ namespace SixLabors.ImageSharp.Tests { TestPngEncoderCore(provider, PngColorType.RgbWithAlpha, compressionLevel, appendCompressionLevel: true); } - + [Theory] [WithFile(TestImages.Png.Palette8Bpp, nameof(PaletteLargeOnly), PixelTypes.Rgba32)] - public void PaletteColorType_WuQuantizer_File( - TestImageProvider provider, - int paletteSize) - where TPixel : struct, IPixel - { - this.PaletteColorType_WuQuantizer(provider, paletteSize); - } - - [Theory] - [WithTestPatternImages(nameof(PaletteSizes), 72, 72, PixelTypes.Rgba32)] public void PaletteColorType_WuQuantizer(TestImageProvider provider, int paletteSize) where TPixel : struct, IPixel { - using (Image image = provider.GetImage()) - { - var encoder = new PngEncoder - { - PngColorType = PngColorType.Palette, - PaletteSize = paletteSize, - Quantizer = new WuQuantizer() - }; - - image.VerifyEncoder(provider, "png", $"PaletteSize-{paletteSize}", encoder, appendPixelTypeToFileName: false); - } + TestPngEncoderCore(provider, PngColorType.Palette, paletteSize: paletteSize, appendPaletteSize: true); } private static bool HasAlpha(PngColorType pngColorType) => @@ -114,9 +94,11 @@ namespace SixLabors.ImageSharp.Tests TestImageProvider provider, PngColorType pngColorType, int compressionLevel = 6, + int paletteSize = 0, bool appendPngColorType = false, bool appendPixelType = false, - bool appendCompressionLevel = false) + bool appendCompressionLevel = false, + bool appendPaletteSize = false) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) @@ -126,24 +108,33 @@ namespace SixLabors.ImageSharp.Tests image.Mutate(c => c.MakeOpaque()); } - var encoder = new PngEncoder { PngColorType = pngColorType, CompressionLevel = compressionLevel}; + var encoder = new PngEncoder + { + PngColorType = pngColorType, + CompressionLevel = compressionLevel, + PaletteSize = paletteSize + }; string pngColorTypeInfo = appendPngColorType ? pngColorType.ToString() : ""; string compressionLevelInfo = appendCompressionLevel ? $"_C{compressionLevel}" : ""; - string debugInfo = $"{pngColorTypeInfo}{compressionLevelInfo}"; - + string paletteSizeInfo = appendPaletteSize ? $"_PaletteSize-{paletteSize}" : ""; + string debugInfo = $"{pngColorTypeInfo}{compressionLevelInfo}{paletteSizeInfo}"; + //string referenceInfo = $"{pngColorTypeInfo}"; + // Does DebugSave & load reference CompareToReferenceInput(): string actualOutputFile = ((ITestImageProvider)provider).Utility.SaveTestOutputFile(image, "png", encoder, debugInfo, appendPixelType); IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile); + string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", debugInfo, appendPixelType); using (var actualImage = Image.Load(actualOutputFile, referenceDecoder)) + using (var referenceImage = Image.Load(referenceOutputFile, referenceDecoder)) { ImageComparer comparer = pngColorType == PngColorType.Palette ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder) : ImageComparer.Exact; - comparer.VerifySimilarity(image, actualImage); + comparer.VerifySimilarity(referenceImage, actualImage); } } } diff --git a/tests/Images/External b/tests/Images/External index b3be1178d..d9c7d3707 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit b3be1178d4e970efc624181480094e50b0d57a90 +Subproject commit d9c7d37074e112eabeccdde6381286f69b01b8b1 From 1e777f595d99ce685a8dc6945a609fc2f9b4a476 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 22 Feb 2018 18:26:01 +0100 Subject: [PATCH 3/3] fixed JpegEncoderTests --- .../Formats/Jpg/JpegEncoderTests.cs | 28 ++++++++++++------- tests/Images/External | 2 +- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 10657ea78..cc030bbf7 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -15,6 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; + using SixLabors.Primitives; using Xunit; using Xunit.Abstractions; @@ -55,20 +56,27 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestJpegEncoderCore(provider, subsample, quality); } - private static ImageComparer GetComparer(int quality) + /// + /// Anton's SUPER-SCIENTIFIC tolerance threshold calculation + /// + private static ImageComparer GetComparer(int quality, JpegSubsample subsample) { - if (quality > 90) - { - return ImageComparer.Tolerant(0.0005f / 100); - } - else if (quality > 50) + float tolerance = 0.015f; // ~1.5% + + if (quality < 50) { - return ImageComparer.Tolerant(0.005f / 100); + tolerance *= 10f; } - else + else if (quality < 75 || subsample == JpegSubsample.Ratio420) { - return ImageComparer.Tolerant(0.01f / 100); + tolerance *= 5f; + if (subsample == JpegSubsample.Ratio420) + { + tolerance *= 2f; + } } + + return ImageComparer.Tolerant(tolerance); } private static void TestJpegEncoderCore( @@ -88,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Quality = quality }; string info = $"{subsample}-Q{quality}"; - ImageComparer comparer = GetComparer(quality); + ImageComparer comparer = GetComparer(quality, subsample); // Does DebugSave & load reference CompareToReferenceInput(): image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png"); diff --git a/tests/Images/External b/tests/Images/External index d9c7d3707..20f83891c 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit d9c7d37074e112eabeccdde6381286f69b01b8b1 +Subproject commit 20f83891ce75597486f5532010a8c5dea1419a4d