diff --git a/.gitattributes b/.gitattributes index 7c648c0774..6f0a3048cf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,9 +2,13 @@ # Set default behavior to: # treat as text and # normalize to Unix-style line endings +############################################################################### * text eol=lf - +############################################################################### # Set explicit file behavior to: +# treat as text and +# normalize to Unix-style line endings +############################################################################### *.asm text eol=lf *.c text eol=lf *.clj text eol=lf @@ -49,19 +53,35 @@ *.txt text eol=lf *.vb text eol=lf *.yml text eol=lf +############################################################################### +# Set explicit file behavior to: # treat as text # normalize to Unix-style line endings and # diff as csharp +############################################################################### *.cs text eol=lf diff=csharp +############################################################################### +# Set explicit file behavior to: +# treat as text +# normalize to Unix-style line endings and # use a union merge when resoling conflicts +############################################################################### *.csproj text eol=lf merge=union *.dbproj text eol=lf merge=union *.fsproj text eol=lf merge=union *.ncrunchproject text eol=lf merge=union *.vbproj text eol=lf merge=union +############################################################################### +# Set explicit file behavior to: +# treat as text # normalize to Windows-style line endings and +# use a union merge when resoling conflicts +############################################################################### *.sln text eol=crlf merge=union +############################################################################### +# Set explicit file behavior to: # treat as binary +############################################################################### *.basis binary *.bmp binary *.dds binary @@ -90,7 +110,10 @@ *.woff2 binary *.xls binary *.xlsx binary +############################################################################### +# Set explicit file behavior to: # diff as plain text +############################################################################### *.doc diff=astextplain *.docx diff=astextplain *.dot diff=astextplain @@ -98,12 +121,4 @@ *.pptx diff=astextplain *.rtf diff=astextplain *.svg diff=astextplain -*.jpg filter=lfs diff=lfs merge=lfs -text -*.jpeg filter=lfs diff=lfs merge=lfs -text -*.bmp filter=lfs diff=lfs merge=lfs -text -*.gif filter=lfs diff=lfs merge=lfs -text -*.png filter=lfs diff=lfs merge=lfs -text -*.tif filter=lfs diff=lfs merge=lfs -text -*.tiff filter=lfs diff=lfs merge=lfs -text -*.tga filter=lfs diff=lfs merge=lfs -text -*.webp filter=lfs diff=lfs merge=lfs -text +*.jpg,*.jpeg,*.bmp,*.gif,*.png,*.tif,*.tiff,*.tga,*.webp filter=lfs diff=lfs merge=lfs -text diff --git a/shared-infrastructure b/shared-infrastructure index 9f515595ee..649bdbe605 160000 --- a/shared-infrastructure +++ b/shared-infrastructure @@ -1 +1 @@ -Subproject commit 9f515595ee8a4c3282fc88113f7f46c676fa3e9d +Subproject commit 649bdbe6050722b030d9292d3fc083cd6ffe87ba diff --git a/src/ImageSharp/ColorSpaces/YCbCr.cs b/src/ImageSharp/ColorSpaces/YCbCr.cs index eaaf7f58f4..b39fe30252 100644 --- a/src/ImageSharp/ColorSpaces/YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/YCbCr.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using System; @@ -100,4 +100,4 @@ public bool Equals(YCbCr other) && this.Cr.Equals(other.Cr); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/BinaryThresholdColorComponent.cs b/src/ImageSharp/Processing/BinaryThresholdColorComponent.cs new file mode 100644 index 0000000000..e46070dcb6 --- /dev/null +++ b/src/ImageSharp/Processing/BinaryThresholdColorComponent.cs @@ -0,0 +1,26 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Processing +{ + /// + /// The color component to be compared to threshold. + /// + public enum BinaryThresholdColorComponent : int + { + /// + /// Luminance color component according to ITU-R Recommendation BT.709. + /// + Luminance = 0, + + /// + /// HSL saturation color component. + /// + Saturation = 1, + + /// + /// Maximum of YCbCr chroma value, i.e. Cb and Cr distance from achromatic value. + /// + MaxChroma = 2, + } +} diff --git a/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs b/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs index d21429589a..11c6433f22 100644 --- a/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Binarization/BinaryThresholdExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.Processing.Processors.Binarization; @@ -11,20 +11,51 @@ namespace SixLabors.ImageSharp.Processing /// public static class BinaryThresholdExtensions { + /// + /// Applies binarization to the image splitting the pixels at the given threshold with + /// Luminance as the color component to be compared to threshold. + /// + /// The image this method extends. + /// The threshold to apply binarization of the image. Must be between 0 and 1. + /// The to allow chaining of operations. + public static IImageProcessingContext BinaryThreshold(this IImageProcessingContext source, float threshold) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdColorComponent.Luminance)); + /// /// Applies binarization to the image splitting the pixels at the given threshold. /// /// The image this method extends. /// The threshold to apply binarization of the image. Must be between 0 and 1. + /// The color component to be compared to threshold. + /// The to allow chaining of operations. + public static IImageProcessingContext BinaryThreshold( + this IImageProcessingContext source, + float threshold, + BinaryThresholdColorComponent colorComponent) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, colorComponent)); + + /// + /// Applies binarization to the image splitting the pixels at the given threshold with + /// Luminance as the color component to be compared to threshold. + /// + /// The image this method extends. + /// The threshold to apply binarization of the image. Must be between 0 and 1. + /// + /// The structure that specifies the portion of the image object to alter. + /// /// The to allow chaining of operations. - public static IImageProcessingContext BinaryThreshold(this IImageProcessingContext source, float threshold) => - source.ApplyProcessor(new BinaryThresholdProcessor(threshold)); + public static IImageProcessingContext BinaryThreshold( + this IImageProcessingContext source, + float threshold, + Rectangle rectangle) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdColorComponent.Luminance), rectangle); /// /// Applies binarization to the image splitting the pixels at the given threshold. /// /// The image this method extends. /// The threshold to apply binarization of the image. Must be between 0 and 1. + /// The color component to be compared to threshold. /// /// The structure that specifies the portion of the image object to alter. /// @@ -32,8 +63,25 @@ public static IImageProcessingContext BinaryThreshold(this IImageProcessingConte public static IImageProcessingContext BinaryThreshold( this IImageProcessingContext source, float threshold, - Rectangle rectangle) => - source.ApplyProcessor(new BinaryThresholdProcessor(threshold), rectangle); + BinaryThresholdColorComponent colorComponent, + Rectangle rectangle) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, colorComponent), rectangle); + + /// + /// Applies binarization to the image splitting the pixels at the given threshold with + /// Luminance as the color component to be compared to threshold. + /// + /// The image this method extends. + /// The threshold to apply binarization of the image. Must be between 0 and 1. + /// The color to use for pixels that are above the threshold. + /// The color to use for pixels that are below the threshold + /// The to allow chaining of operations. + public static IImageProcessingContext BinaryThreshold( + this IImageProcessingContext source, + float threshold, + Color upperColor, + Color lowerColor) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance)); /// /// Applies binarization to the image splitting the pixels at the given threshold. @@ -42,13 +90,35 @@ public static IImageProcessingContext BinaryThreshold( /// The threshold to apply binarization of the image. Must be between 0 and 1. /// The color to use for pixels that are above the threshold. /// The color to use for pixels that are below the threshold + /// The color component to be compared to threshold. /// The to allow chaining of operations. public static IImageProcessingContext BinaryThreshold( this IImageProcessingContext source, float threshold, Color upperColor, - Color lowerColor) => - source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor)); + Color lowerColor, + BinaryThresholdColorComponent colorComponent) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, colorComponent)); + + /// + /// Applies binarization to the image splitting the pixels at the given threshold with + /// Luminance as the color component to be compared to threshold. + /// + /// The image this method extends. + /// The threshold to apply binarization of the image. Must be between 0 and 1. + /// The color to use for pixels that are above the threshold. + /// The color to use for pixels that are below the threshold + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The to allow chaining of operations. + public static IImageProcessingContext BinaryThreshold( + this IImageProcessingContext source, + float threshold, + Color upperColor, + Color lowerColor, + Rectangle rectangle) + => source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance), rectangle); /// /// Applies binarization to the image splitting the pixels at the given threshold. @@ -57,6 +127,7 @@ public static IImageProcessingContext BinaryThreshold( /// The threshold to apply binarization of the image. Must be between 0 and 1. /// The color to use for pixels that are above the threshold. /// The color to use for pixels that are below the threshold + /// The color component to be compared to threshold. /// /// The structure that specifies the portion of the image object to alter. /// @@ -66,7 +137,8 @@ public static IImageProcessingContext BinaryThreshold( float threshold, Color upperColor, Color lowerColor, + BinaryThresholdColorComponent colorComponent, Rectangle rectangle) => - source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor), rectangle); + source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, colorComponent), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs index 460a82f0a0..24a3e6c1da 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs @@ -14,8 +14,19 @@ public class BinaryThresholdProcessor : IImageProcessor /// Initializes a new instance of the class. /// /// The threshold to split the image. Must be between 0 and 1. + /// The color component to be compared to threshold. + public BinaryThresholdProcessor(float threshold, BinaryThresholdColorComponent colorComponent) + : this(threshold, Color.White, Color.Black, colorComponent) + { + } + + /// + /// Initializes a new instance of the class with + /// Luminance as color component to be compared to threshold. + /// + /// The threshold to split the image. Must be between 0 and 1. public BinaryThresholdProcessor(float threshold) - : this(threshold, Color.White, Color.Black) + : this(threshold, Color.White, Color.Black, BinaryThresholdColorComponent.Luminance) { } @@ -25,12 +36,26 @@ public BinaryThresholdProcessor(float threshold) /// The threshold to split the image. Must be between 0 and 1. /// The color to use for pixels that are above the threshold. /// The color to use for pixels that are below the threshold. - public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor) + /// The color component to be compared to threshold. + public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor, BinaryThresholdColorComponent colorComponent) { Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); this.Threshold = threshold; this.UpperColor = upperColor; this.LowerColor = lowerColor; + this.ColorComponent = colorComponent; + } + + /// + /// Initializes a new instance of the class with + /// Luminance as color component to be compared to threshold. + /// + /// The threshold to split the image. Must be between 0 and 1. + /// The color to use for pixels that are above the threshold. + /// The color to use for pixels that are below the threshold. + public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor) + : this(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance) + { } /// @@ -48,7 +73,12 @@ public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerCo /// public Color LowerColor { get; } - /// + /// + /// Gets a value indicating whether to use saturation value instead of luminance. + /// + public BinaryThresholdColorComponent ColorComponent { get; } + + /// public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle) where TPixel : unmanaged, IPixel => new BinaryThresholdProcessor(configuration, this, source, sourceRectangle); diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs index df95b6f1b6..aa03cc27d2 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; @@ -27,9 +26,7 @@ internal class BinaryThresholdProcessor : ImageProcessor /// The source area to process for the current processor instance. public BinaryThresholdProcessor(Configuration configuration, BinaryThresholdProcessor definition, Image source, Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) - { - this.definition = definition; - } + => this.definition = definition; /// protected override void OnFrameApply(ImageFrame source) @@ -42,10 +39,16 @@ protected override void OnFrameApply(ImageFrame source) Configuration configuration = this.Configuration; var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); - bool isAlphaOnly = typeof(TPixel) == typeof(A8); + var operation = new RowOperation( + interest.X, + source, + upper, + lower, + threshold, + this.definition.ColorComponent, + configuration); - var operation = new RowOperation(interest, source, upper, lower, threshold, isAlphaOnly); - ParallelRowIterator.IterateRows( + ParallelRowIterator.IterateRows( configuration, interest, in operation); @@ -54,51 +57,131 @@ protected override void OnFrameApply(ImageFrame source) /// /// A implementing the clone logic for . /// - private readonly struct RowOperation : IRowOperation + private readonly struct RowOperation : IRowOperation { private readonly ImageFrame source; private readonly TPixel upper; private readonly TPixel lower; private readonly byte threshold; - private readonly int minX; - private readonly int maxX; - private readonly bool isAlphaOnly; + private readonly BinaryThresholdColorComponent colorComponent; + private readonly int startX; + private readonly Configuration configuration; [MethodImpl(InliningOptions.ShortMethod)] public RowOperation( - Rectangle bounds, + int startX, ImageFrame source, TPixel upper, TPixel lower, byte threshold, - bool isAlphaOnly) + BinaryThresholdColorComponent colorComponent, + Configuration configuration) { + this.startX = startX; this.source = source; this.upper = upper; this.lower = lower; this.threshold = threshold; - this.minX = bounds.X; - this.maxX = bounds.Right; - this.isAlphaOnly = isAlphaOnly; + this.colorComponent = colorComponent; + this.configuration = configuration; } /// - [MethodImpl(InliningOptions.ShortMethod)] - public void Invoke(int y) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Invoke(int y, Span span) + { + TPixel upper = this.upper; + TPixel lower = this.lower; + + Span rowSpan = this.source.GetPixelRowSpan(y).Slice(this.startX, span.Length); + PixelOperations.Instance.ToRgb24(this.configuration, rowSpan, span); + + switch (this.colorComponent) + { + case BinaryThresholdColorComponent.Luminance: + { + byte threshold = this.threshold; + for (int x = 0; x < rowSpan.Length; x++) + { + Rgb24 rgb = span[x]; + byte luminance = ColorNumerics.Get8BitBT709Luminance(rgb.R, rgb.G, rgb.B); + ref TPixel color = ref rowSpan[x]; + color = luminance >= threshold ? upper : lower; + } + + break; + } + + case BinaryThresholdColorComponent.Saturation: + { + float threshold = this.threshold / 255F; + for (int x = 0; x < rowSpan.Length; x++) + { + float saturation = GetSaturation(span[x]); + ref TPixel color = ref rowSpan[x]; + color = saturation >= threshold ? upper : lower; + } + + break; + } + + case BinaryThresholdColorComponent.MaxChroma: + { + float threshold = this.threshold / 2F; + for (int x = 0; x < rowSpan.Length; x++) + { + float chroma = GetMaxChroma(span[x]); + ref TPixel color = ref rowSpan[x]; + color = chroma >= threshold ? upper : lower; + } + + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float GetSaturation(Rgb24 rgb) { - Rgba32 rgba = default; - Span row = this.source.GetPixelRowSpan(y); - ref TPixel rowRef = ref MemoryMarshal.GetReference(row); + // Slimmed down RGB => HSL formula. See HslAndRgbConverter. + float r = rgb.R / 255F; + float g = rgb.G / 255F; + float b = rgb.B / 255F; - for (int x = this.minX; x < this.maxX; x++) + float max = MathF.Max(r, MathF.Max(g, b)); + float min = MathF.Min(r, MathF.Min(g, b)); + float chroma = max - min; + + if (MathF.Abs(chroma) < Constants.Epsilon) { - ref TPixel color = ref Unsafe.Add(ref rowRef, x); - color.ToRgba32(ref rgba); + return 0F; + } - // Convert to grayscale using ITU-R Recommendation BT.709 if required - byte luminance = this.isAlphaOnly ? rgba.A : ColorNumerics.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B); - color = luminance >= this.threshold ? this.upper : this.lower; + float l = (max + min) / 2F; + + if (l <= .5F) + { + return chroma / (max + min); } + else + { + return chroma / (2F - max - min); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float GetMaxChroma(Rgb24 rgb) + { + // Slimmed down RGB => YCbCr formula. See YCbCrAndRgbConverter. + float r = rgb.R; + float g = rgb.G; + float b = rgb.B; + const float achromatic = 127.5F; + + float cb = 128F + ((-0.168736F * r) - (0.331264F * g) + (0.5F * b)); + float cr = 128F + ((0.5F * r) - (0.418688F * g) - (0.081312F * b)); + + return MathF.Max(MathF.Abs(cb - achromatic), MathF.Abs(cr - achromatic)); } } } diff --git a/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs b/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs index 5bdfda02eb..a02ca36eeb 100644 --- a/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs +++ b/tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.Processing; @@ -16,6 +16,7 @@ public void BinaryThreshold_CorrectProcessor() this.operations.BinaryThreshold(.23f); BinaryThresholdProcessor p = this.Verify(); Assert.Equal(.23f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent); Assert.Equal(Color.White, p.UpperColor); Assert.Equal(Color.Black, p.LowerColor); } @@ -26,6 +27,7 @@ public void BinaryThreshold_rect_CorrectProcessor() this.operations.BinaryThreshold(.93f, this.rect); BinaryThresholdProcessor p = this.Verify(this.rect); Assert.Equal(.93f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent); Assert.Equal(Color.White, p.UpperColor); Assert.Equal(Color.Black, p.LowerColor); } @@ -36,6 +38,7 @@ public void BinaryThreshold_CorrectProcessorWithUpperLower() this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow); BinaryThresholdProcessor p = this.Verify(); Assert.Equal(.23f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent); Assert.Equal(Color.HotPink, p.UpperColor); Assert.Equal(Color.Yellow, p.LowerColor); } @@ -45,9 +48,98 @@ public void BinaryThreshold_rect_CorrectProcessorWithUpperLower() { this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, this.rect); BinaryThresholdProcessor p = this.Verify(this.rect); + Assert.Equal(BinaryThresholdColorComponent.Luminance, p.ColorComponent); Assert.Equal(.93f, p.Threshold); Assert.Equal(Color.HotPink, p.UpperColor); Assert.Equal(Color.Yellow, p.LowerColor); } + + [Fact] + public void BinarySaturationThreshold_CorrectProcessor() + { + this.operations.BinaryThreshold(.23f, BinaryThresholdColorComponent.Saturation); + BinaryThresholdProcessor p = this.Verify(); + Assert.Equal(.23f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent); + Assert.Equal(Color.White, p.UpperColor); + Assert.Equal(Color.Black, p.LowerColor); + } + + [Fact] + public void BinarySaturationThreshold_rect_CorrectProcessor() + { + this.operations.BinaryThreshold(.93f, BinaryThresholdColorComponent.Saturation, this.rect); + BinaryThresholdProcessor p = this.Verify(this.rect); + Assert.Equal(.93f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent); + Assert.Equal(Color.White, p.UpperColor); + Assert.Equal(Color.Black, p.LowerColor); + } + + [Fact] + public void BinarySaturationThreshold_CorrectProcessorWithUpperLower() + { + this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.Saturation); + BinaryThresholdProcessor p = this.Verify(); + Assert.Equal(.23f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent); + Assert.Equal(Color.HotPink, p.UpperColor); + Assert.Equal(Color.Yellow, p.LowerColor); + } + + [Fact] + public void BinarySaturationThreshold_rect_CorrectProcessorWithUpperLower() + { + this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.Saturation, this.rect); + BinaryThresholdProcessor p = this.Verify(this.rect); + Assert.Equal(.93f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.Saturation, p.ColorComponent); + Assert.Equal(Color.HotPink, p.UpperColor); + Assert.Equal(Color.Yellow, p.LowerColor); + } + + [Fact] + public void BinaryMaxChromaThreshold_CorrectProcessor() + { + this.operations.BinaryThreshold(.23f, BinaryThresholdColorComponent.MaxChroma); + BinaryThresholdProcessor p = this.Verify(); + Assert.Equal(.23f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent); + Assert.Equal(Color.White, p.UpperColor); + Assert.Equal(Color.Black, p.LowerColor); + } + + [Fact] + public void BinaryMaxChromaThreshold_rect_CorrectProcessor() + { + this.operations.BinaryThreshold(.93f, BinaryThresholdColorComponent.MaxChroma, this.rect); + BinaryThresholdProcessor p = this.Verify(this.rect); + Assert.Equal(.93f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent); + Assert.Equal(Color.White, p.UpperColor); + Assert.Equal(Color.Black, p.LowerColor); + } + + [Fact] + public void BinaryMaxChromaThreshold_CorrectProcessorWithUpperLower() + { + this.operations.BinaryThreshold(.23f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.MaxChroma); + BinaryThresholdProcessor p = this.Verify(); + Assert.Equal(.23f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent); + Assert.Equal(Color.HotPink, p.UpperColor); + Assert.Equal(Color.Yellow, p.LowerColor); + } + + [Fact] + public void BinaryMaxChromaThreshold_rect_CorrectProcessorWithUpperLower() + { + this.operations.BinaryThreshold(.93f, Color.HotPink, Color.Yellow, BinaryThresholdColorComponent.MaxChroma, this.rect); + BinaryThresholdProcessor p = this.Verify(this.rect); + Assert.Equal(.93f, p.Threshold); + Assert.Equal(BinaryThresholdColorComponent.MaxChroma, p.ColorComponent); + Assert.Equal(Color.HotPink, p.UpperColor); + Assert.Equal(Color.Yellow, p.LowerColor); + } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs index c5b7808cc2..79ed4c7cdb 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs @@ -1,14 +1,15 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System.Globalization; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Binarization; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; namespace SixLabors.ImageSharp.Tests.Processing.Processors.Binarization { - using SixLabors.ImageSharp.Processing; - public class BinaryThresholdTest { public static readonly TheoryData BinaryThresholdValues @@ -19,9 +20,10 @@ public static readonly TheoryData BinaryThresholdValues }; public static readonly string[] CommonTestImages = - { - TestImages.Png.CalliphoraPartial, TestImages.Png.Bike - }; + { + TestImages.Png.Rgb48Bpp, + TestImages.Png.ColorsSaturationLightness, + }; public const PixelTypes TestPixelTypes = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Rgb24; @@ -43,9 +45,9 @@ public void ImageShouldApplyBinaryThresholdInBox(TestImageProvider { using (Image source = provider.GetImage()) - using (var image = source.Clone()) + using (Image image = source.Clone()) { - var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); + var bounds = new Rectangle(image.Width / 8, image.Height / 8, 6 * image.Width / 8, 6 * image.Width / 8); image.Mutate(x => x.BinaryThreshold(value, bounds)); image.DebugSave(provider, value); @@ -53,5 +55,81 @@ public void ImageShouldApplyBinaryThresholdInBox(TestImageProvider(TestImageProvider provider, float value) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage()) + { + image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.Saturation)); + image.DebugSave(provider, value); + image.CompareToReferenceOutput(ImageComparer.Exact, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo)); + } + } + + [Theory] + [WithFileCollection(nameof(CommonTestImages), nameof(BinaryThresholdValues), PixelTypes.Rgba32)] + public void ImageShouldApplyBinarySaturationThresholdInBox(TestImageProvider provider, float value) + where TPixel : unmanaged, IPixel + { + using (Image source = provider.GetImage()) + using (Image image = source.Clone()) + { + var bounds = new Rectangle(image.Width / 8, image.Height / 8, 6 * image.Width / 8, 6 * image.Width / 8); + + image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.Saturation, bounds)); + image.DebugSave(provider, value); + image.CompareToReferenceOutput(ImageComparer.Exact, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo)); + } + } + + [Theory] + [WithFileCollection(nameof(CommonTestImages), nameof(BinaryThresholdValues), PixelTypes.Rgba32)] + public void ImageShouldApplyBinaryMaxChromaThresholdFilter(TestImageProvider provider, float value) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage()) + { + image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.MaxChroma)); + image.DebugSave(provider, value); + + if (!TestEnvironment.Is64BitProcess && TestEnvironment.IsFramework) + { + var comparer = ImageComparer.TolerantPercentage(0.0004F); + image.CompareToReferenceOutput(comparer, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo)); + } + else + { + image.CompareToReferenceOutput(ImageComparer.Exact, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo)); + } + } + } + + [Theory] + [WithFileCollection(nameof(CommonTestImages), nameof(BinaryThresholdValues), PixelTypes.Rgba32)] + public void ImageShouldApplyBinaryMaxChromaThresholdInBox(TestImageProvider provider, float value) + where TPixel : unmanaged, IPixel + { + using (Image source = provider.GetImage()) + using (Image image = source.Clone()) + { + var bounds = new Rectangle(image.Width / 8, image.Height / 8, 6 * image.Width / 8, 6 * image.Width / 8); + + image.Mutate(x => x.BinaryThreshold(value, BinaryThresholdColorComponent.MaxChroma, bounds)); + image.DebugSave(provider, value); + + if (!TestEnvironment.Is64BitProcess && TestEnvironment.IsFramework) + { + var comparer = ImageComparer.TolerantPercentage(0.0004F); + image.CompareToReferenceOutput(comparer, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo)); + } + else + { + image.CompareToReferenceOutput(ImageComparer.Exact, provider, value.ToString("0.00", NumberFormatInfo.InvariantInfo)); + } + } + } } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index ac9d6422aa..c15327e0de 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -40,6 +40,7 @@ public static class Png public const string Rgb48BppInterlaced = "Png/rgb-48bpp-interlaced.png"; public const string Rgb48BppTrans = "Png/rgb-16-tRNS.png"; public const string Rgba64Bpp = "Png/rgb-16-alpha.png"; + public const string ColorsSaturationLightness = "Png/colors-saturation-lightness.png"; public const string CalliphoraPartial = "Png/CalliphoraPartial.png"; public const string CalliphoraPartialGrayscale = "Png/CalliphoraPartialGrayscale.png"; public const string Bike = "Png/Bike.png"; diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs index 8d1b0f7938..cb8a0df42f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs @@ -7,7 +7,6 @@ using System.Linq; using System.Reflection; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Tests { @@ -25,19 +24,11 @@ public static partial class TestEnvironment private static readonly Lazy SolutionDirectoryFullPathLazy = new Lazy(GetSolutionDirectoryFullPathImpl); - private static readonly Lazy RunsOnCiLazy = new Lazy( - () => - { - bool isCi; - return bool.TryParse(Environment.GetEnvironmentVariable("CI"), out isCi) && isCi; - }); + private static readonly Lazy RunsOnCiLazy = new Lazy(() => bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCi) && isCi); private static readonly Lazy NetCoreVersionLazy = new Lazy(GetNetCoreVersion); - static TestEnvironment() - { - PrepareRemoteExecutor(); - } + static TestEnvironment() => PrepareRemoteExecutor(); /// /// Gets the .NET Core version, if running on .NET Core, otherwise returns an empty string. diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png new file mode 100644 index 0000000000..2493321a4c --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51cb254212641ec3d81a7d412cc31c2e0e6b006581796d7507af15127e1d08a9 +size 7913 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png new file mode 100644 index 0000000000..5d8e11424e --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc004ff9b47bcd9300b7dfbd14f2351f17ed4bff205f90845aac823713531dfc +size 4388 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_rgb-48bpp_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_rgb-48bpp_0.25.png new file mode 100644 index 0000000000..58f41d1a6e --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_rgb-48bpp_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0110c27732a1986430589bd9caf849f92525b5dae7be820879883cec7dbd14f +size 10367 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_rgb-48bpp_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_rgb-48bpp_0.75.png new file mode 100644 index 0000000000..47e82d92e1 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdFilter_Rgba32_rgb-48bpp_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:428c04136ce785178f498d2496d395fd173c35593a290da3224ac798041bf7da +size 9843 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png new file mode 100644 index 0000000000..be28e7de22 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11d9396bf4d48bd2dccdc2e4d9d0fe3bd2d1b1b774453151e520db7fb1c0bfac +size 325147 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png new file mode 100644 index 0000000000..c24432571b --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c350a217923d4812599bf7d53d0dc1d69384bf44ce08b348c5c0d7d41cf63c2 +size 324065 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_rgb-48bpp_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_rgb-48bpp_0.25.png new file mode 100644 index 0000000000..2f8536385b --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_rgb-48bpp_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e936af882acaa38d82aef579b976c3d6183482e7b9611a0dd9868056f0190647 +size 316095 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_rgb-48bpp_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_rgb-48bpp_0.75.png new file mode 100644 index 0000000000..4d82cc2d97 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryMaxChromaThresholdInBox_Rgba32_rgb-48bpp_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b43edc1dea9209588dd81fc21cec9ae9dd067e74df7c6d157519371e21c54292 +size 316286 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png new file mode 100644 index 0000000000..96658289aa --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0565725dc6b81dab6e4553b5d1956f7fdce5d442c99af9d3bd4eca5faafb2a4c +size 9120 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png new file mode 100644 index 0000000000..e437183049 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2fac1d23e6638ff2479ea6010a1466651b6a9b2e4e8ab1c5309361682377175 +size 8501 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_rgb-48bpp_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_rgb-48bpp_0.25.png new file mode 100644 index 0000000000..3b7ba96029 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_rgb-48bpp_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ade68e760e7aa28499ba7fa9324027b66d377438565901b4bf3db40ebb95c3f +size 9795 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_rgb-48bpp_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_rgb-48bpp_0.75.png new file mode 100644 index 0000000000..64d4620f88 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdFilter_Rgba32_rgb-48bpp_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:351b945c4f1ae794d166a141d745c509003147e54fc735c3a97987b7912bf1f0 +size 10813 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png new file mode 100644 index 0000000000..11fedec168 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cb7b90177c8f136accea0e5649fcf91c5467cac8310c39818001bd67ade1931 +size 325514 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png new file mode 100644 index 0000000000..4c1009b8fd --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8058aba0e2f553d9badd6bc12b152465fd8bd3dfb0933d303a565c3472b8cf91 +size 325033 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_rgb-48bpp_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_rgb-48bpp_0.25.png new file mode 100644 index 0000000000..2ccba1fdaf --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_rgb-48bpp_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:260a432d56e9972a4b0617c47c81090dd768363eac3cae27c91a4176eac30fde +size 315799 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_rgb-48bpp_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_rgb-48bpp_0.75.png new file mode 100644 index 0000000000..4d42e08c3c --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinarySaturationThresholdInBox_Rgba32_rgb-48bpp_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0abfdf31816948bb3ea72b2d4b1ea0d6e648c87e8f2283e38cf133505f1d39c +size 316284 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png new file mode 100644 index 0000000000..5cd2ac4066 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_colors-saturation-lightness_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffe0d135aa932ec246edca7124a550121acd090d7d56c8cb3f1d80cd6139831f +size 6906 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png new file mode 100644 index 0000000000..bd7ad3e9a2 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_colors-saturation-lightness_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b76320eec406b546e6d9e7c00f01faf4528d1e5573b52665df4664392b406c6a +size 6708 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_rgb-48bpp_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_rgb-48bpp_0.25.png new file mode 100644 index 0000000000..a94e4a7559 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_rgb-48bpp_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ade047ec10bfd20a7ac0205c9aff3bda33607883291d4fe23704ac8864ac239 +size 8066 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_rgb-48bpp_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_rgb-48bpp_0.75.png new file mode 100644 index 0000000000..15a94b2bee --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdFilter_Rgba32_rgb-48bpp_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbe9c25d68423cba508713f85c4753c302dbf95afec45a0ed5bc21299438e222 +size 6817 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png new file mode 100644 index 0000000000..6969b25924 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_colors-saturation-lightness_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7427a84c0ea1cb41543604eeb8aba6bfad15799c9814e7a9e8346bea2c01a354 +size 324724 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png new file mode 100644 index 0000000000..84895fa885 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_colors-saturation-lightness_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7408fa9679d211fc161b89850e6e68cb90719ddc4d1d7ff4d029debbac24e32 +size 325185 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_rgb-48bpp_0.25.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_rgb-48bpp_0.25.png new file mode 100644 index 0000000000..bc9ca43a47 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_rgb-48bpp_0.25.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0f34b0685e327e986186775288fb034d9154073c2986c714eb59eae7f4112bf +size 315109 diff --git a/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_rgb-48bpp_0.75.png b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_rgb-48bpp_0.75.png new file mode 100644 index 0000000000..fe1af1539b --- /dev/null +++ b/tests/Images/External/ReferenceOutput/BinaryThresholdTest/ImageShouldApplyBinaryThresholdInBox_Rgba32_rgb-48bpp_0.75.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51a988d37b88327b244b7ca991c225550b5e5ba1e5322c0756a8108e7cf6cb98 +size 314609 diff --git a/tests/Images/Input/Png/colors-saturation-lightness.png b/tests/Images/Input/Png/colors-saturation-lightness.png new file mode 100644 index 0000000000..7af32025c7 --- /dev/null +++ b/tests/Images/Input/Png/colors-saturation-lightness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bccb0284da98a4edd0a6262ac6a608e252f88c7c63321098b24e9cc11d7a201c +size 146402