Skip to content

Commit 6038be9

Browse files
Merge pull request #1555 from Franz1960/max-chroma-binarization
New overloads for binary threshold operations. The new argument Color…
2 parents 2ae6018 + 045612f commit 6038be9

File tree

36 files changed

+535
-72
lines changed

36 files changed

+535
-72
lines changed

.gitattributes

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
# Set default behavior to:
33
# treat as text and
44
# normalize to Unix-style line endings
5+
###############################################################################
56
* text eol=lf
6-
7+
###############################################################################
78
# Set explicit file behavior to:
9+
# treat as text and
10+
# normalize to Unix-style line endings
11+
###############################################################################
812
*.asm text eol=lf
913
*.c text eol=lf
1014
*.clj text eol=lf
@@ -49,19 +53,35 @@
4953
*.txt text eol=lf
5054
*.vb text eol=lf
5155
*.yml text eol=lf
56+
###############################################################################
57+
# Set explicit file behavior to:
5258
# treat as text
5359
# normalize to Unix-style line endings and
5460
# diff as csharp
61+
###############################################################################
5562
*.cs text eol=lf diff=csharp
63+
###############################################################################
64+
# Set explicit file behavior to:
65+
# treat as text
66+
# normalize to Unix-style line endings and
5667
# use a union merge when resoling conflicts
68+
###############################################################################
5769
*.csproj text eol=lf merge=union
5870
*.dbproj text eol=lf merge=union
5971
*.fsproj text eol=lf merge=union
6072
*.ncrunchproject text eol=lf merge=union
6173
*.vbproj text eol=lf merge=union
74+
###############################################################################
75+
# Set explicit file behavior to:
76+
# treat as text
6277
# normalize to Windows-style line endings and
78+
# use a union merge when resoling conflicts
79+
###############################################################################
6380
*.sln text eol=crlf merge=union
81+
###############################################################################
82+
# Set explicit file behavior to:
6483
# treat as binary
84+
###############################################################################
6585
*.basis binary
6686
*.bmp binary
6787
*.dds binary
@@ -90,20 +110,15 @@
90110
*.woff2 binary
91111
*.xls binary
92112
*.xlsx binary
113+
###############################################################################
114+
# Set explicit file behavior to:
93115
# diff as plain text
116+
###############################################################################
94117
*.doc diff=astextplain
95118
*.docx diff=astextplain
96119
*.dot diff=astextplain
97120
*.pdf diff=astextplain
98121
*.pptx diff=astextplain
99122
*.rtf diff=astextplain
100123
*.svg diff=astextplain
101-
*.jpg filter=lfs diff=lfs merge=lfs -text
102-
*.jpeg filter=lfs diff=lfs merge=lfs -text
103-
*.bmp filter=lfs diff=lfs merge=lfs -text
104-
*.gif filter=lfs diff=lfs merge=lfs -text
105-
*.png filter=lfs diff=lfs merge=lfs -text
106-
*.tif filter=lfs diff=lfs merge=lfs -text
107-
*.tiff filter=lfs diff=lfs merge=lfs -text
108-
*.tga filter=lfs diff=lfs merge=lfs -text
109-
*.webp filter=lfs diff=lfs merge=lfs -text
124+
*.jpg,*.jpeg,*.bmp,*.gif,*.png,*.tif,*.tiff,*.tga,*.webp filter=lfs diff=lfs merge=lfs -text

shared-infrastructure

src/ImageSharp/ColorSpaces/YCbCr.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
@@ -100,4 +100,4 @@ public bool Equals(YCbCr other)
100100
&& this.Cr.Equals(other.Cr);
101101
}
102102
}
103-
}
103+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
namespace SixLabors.ImageSharp.Processing
5+
{
6+
/// <summary>
7+
/// The color component to be compared to threshold.
8+
/// </summary>
9+
public enum BinaryThresholdColorComponent : int
10+
{
11+
/// <summary>
12+
/// Luminance color component according to ITU-R Recommendation BT.709.
13+
/// </summary>
14+
Luminance = 0,
15+
16+
/// <summary>
17+
/// HSL saturation color component.
18+
/// </summary>
19+
Saturation = 1,
20+
21+
/// <summary>
22+
/// Maximum of YCbCr chroma value, i.e. Cb and Cr distance from achromatic value.
23+
/// </summary>
24+
MaxChroma = 2,
25+
}
26+
}
Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using SixLabors.ImageSharp.Processing.Processors.Binarization;
@@ -11,29 +11,77 @@ namespace SixLabors.ImageSharp.Processing
1111
/// </summary>
1212
public static class BinaryThresholdExtensions
1313
{
14+
/// <summary>
15+
/// Applies binarization to the image splitting the pixels at the given threshold with
16+
/// Luminance as the color component to be compared to threshold.
17+
/// </summary>
18+
/// <param name="source">The image this method extends.</param>
19+
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
20+
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
21+
public static IImageProcessingContext BinaryThreshold(this IImageProcessingContext source, float threshold)
22+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdColorComponent.Luminance));
23+
1424
/// <summary>
1525
/// Applies binarization to the image splitting the pixels at the given threshold.
1626
/// </summary>
1727
/// <param name="source">The image this method extends.</param>
1828
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
29+
/// <param name="colorComponent">The color component to be compared to threshold.</param>
30+
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
31+
public static IImageProcessingContext BinaryThreshold(
32+
this IImageProcessingContext source,
33+
float threshold,
34+
BinaryThresholdColorComponent colorComponent)
35+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, colorComponent));
36+
37+
/// <summary>
38+
/// Applies binarization to the image splitting the pixels at the given threshold with
39+
/// Luminance as the color component to be compared to threshold.
40+
/// </summary>
41+
/// <param name="source">The image this method extends.</param>
42+
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
43+
/// <param name="rectangle">
44+
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
45+
/// </param>
1946
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
20-
public static IImageProcessingContext BinaryThreshold(this IImageProcessingContext source, float threshold) =>
21-
source.ApplyProcessor(new BinaryThresholdProcessor(threshold));
47+
public static IImageProcessingContext BinaryThreshold(
48+
this IImageProcessingContext source,
49+
float threshold,
50+
Rectangle rectangle)
51+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, BinaryThresholdColorComponent.Luminance), rectangle);
2252

2353
/// <summary>
2454
/// Applies binarization to the image splitting the pixels at the given threshold.
2555
/// </summary>
2656
/// <param name="source">The image this method extends.</param>
2757
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
58+
/// <param name="colorComponent">The color component to be compared to threshold.</param>
2859
/// <param name="rectangle">
2960
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
3061
/// </param>
3162
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
3263
public static IImageProcessingContext BinaryThreshold(
3364
this IImageProcessingContext source,
3465
float threshold,
35-
Rectangle rectangle) =>
36-
source.ApplyProcessor(new BinaryThresholdProcessor(threshold), rectangle);
66+
BinaryThresholdColorComponent colorComponent,
67+
Rectangle rectangle)
68+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, colorComponent), rectangle);
69+
70+
/// <summary>
71+
/// Applies binarization to the image splitting the pixels at the given threshold with
72+
/// Luminance as the color component to be compared to threshold.
73+
/// </summary>
74+
/// <param name="source">The image this method extends.</param>
75+
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
76+
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
77+
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
78+
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
79+
public static IImageProcessingContext BinaryThreshold(
80+
this IImageProcessingContext source,
81+
float threshold,
82+
Color upperColor,
83+
Color lowerColor)
84+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance));
3785

3886
/// <summary>
3987
/// Applies binarization to the image splitting the pixels at the given threshold.
@@ -42,13 +90,35 @@ public static IImageProcessingContext BinaryThreshold(
4290
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
4391
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
4492
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
93+
/// <param name="colorComponent">The color component to be compared to threshold.</param>
4594
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
4695
public static IImageProcessingContext BinaryThreshold(
4796
this IImageProcessingContext source,
4897
float threshold,
4998
Color upperColor,
50-
Color lowerColor) =>
51-
source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor));
99+
Color lowerColor,
100+
BinaryThresholdColorComponent colorComponent)
101+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, colorComponent));
102+
103+
/// <summary>
104+
/// Applies binarization to the image splitting the pixels at the given threshold with
105+
/// Luminance as the color component to be compared to threshold.
106+
/// </summary>
107+
/// <param name="source">The image this method extends.</param>
108+
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
109+
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
110+
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
111+
/// <param name="rectangle">
112+
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
113+
/// </param>
114+
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
115+
public static IImageProcessingContext BinaryThreshold(
116+
this IImageProcessingContext source,
117+
float threshold,
118+
Color upperColor,
119+
Color lowerColor,
120+
Rectangle rectangle)
121+
=> source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance), rectangle);
52122

53123
/// <summary>
54124
/// Applies binarization to the image splitting the pixels at the given threshold.
@@ -57,6 +127,7 @@ public static IImageProcessingContext BinaryThreshold(
57127
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
58128
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
59129
/// <param name="lowerColor">The color to use for pixels that are below the threshold</param>
130+
/// <param name="colorComponent">The color component to be compared to threshold.</param>
60131
/// <param name="rectangle">
61132
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
62133
/// </param>
@@ -66,7 +137,8 @@ public static IImageProcessingContext BinaryThreshold(
66137
float threshold,
67138
Color upperColor,
68139
Color lowerColor,
140+
BinaryThresholdColorComponent colorComponent,
69141
Rectangle rectangle) =>
70-
source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor), rectangle);
142+
source.ApplyProcessor(new BinaryThresholdProcessor(threshold, upperColor, lowerColor, colorComponent), rectangle);
71143
}
72-
}
144+
}

src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,19 @@ public class BinaryThresholdProcessor : IImageProcessor
1414
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor"/> class.
1515
/// </summary>
1616
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
17+
/// <param name="colorComponent">The color component to be compared to threshold.</param>
18+
public BinaryThresholdProcessor(float threshold, BinaryThresholdColorComponent colorComponent)
19+
: this(threshold, Color.White, Color.Black, colorComponent)
20+
{
21+
}
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor"/> class with
25+
/// Luminance as color component to be compared to threshold.
26+
/// </summary>
27+
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
1728
public BinaryThresholdProcessor(float threshold)
18-
: this(threshold, Color.White, Color.Black)
29+
: this(threshold, Color.White, Color.Black, BinaryThresholdColorComponent.Luminance)
1930
{
2031
}
2132

@@ -25,12 +36,26 @@ public BinaryThresholdProcessor(float threshold)
2536
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
2637
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
2738
/// <param name="lowerColor">The color to use for pixels that are below the threshold.</param>
28-
public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor)
39+
/// <param name="colorComponent">The color component to be compared to threshold.</param>
40+
public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor, BinaryThresholdColorComponent colorComponent)
2941
{
3042
Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
3143
this.Threshold = threshold;
3244
this.UpperColor = upperColor;
3345
this.LowerColor = lowerColor;
46+
this.ColorComponent = colorComponent;
47+
}
48+
49+
/// <summary>
50+
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor"/> class with
51+
/// Luminance as color component to be compared to threshold.
52+
/// </summary>
53+
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
54+
/// <param name="upperColor">The color to use for pixels that are above the threshold.</param>
55+
/// <param name="lowerColor">The color to use for pixels that are below the threshold.</param>
56+
public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerColor)
57+
: this(threshold, upperColor, lowerColor, BinaryThresholdColorComponent.Luminance)
58+
{
3459
}
3560

3661
/// <summary>
@@ -48,7 +73,12 @@ public BinaryThresholdProcessor(float threshold, Color upperColor, Color lowerCo
4873
/// </summary>
4974
public Color LowerColor { get; }
5075

51-
/// <inheritdoc />
76+
/// <summary>
77+
/// Gets a value indicating whether to use saturation value instead of luminance.
78+
/// </summary>
79+
public BinaryThresholdColorComponent ColorComponent { get; }
80+
81+
/// <inheritdoc />
5282
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>(Configuration configuration, Image<TPixel> source, Rectangle sourceRectangle)
5383
where TPixel : unmanaged, IPixel<TPixel>
5484
=> new BinaryThresholdProcessor<TPixel>(configuration, this, source, sourceRectangle);

0 commit comments

Comments
 (0)