diff --git a/src/ImageSharp/Processing/Extensions/LightnessExtensions.cs b/src/ImageSharp/Processing/Extensions/LightnessExtensions.cs
new file mode 100644
index 000000000..86db9509e
--- /dev/null
+++ b/src/ImageSharp/Processing/Extensions/LightnessExtensions.cs
@@ -0,0 +1,44 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Processing.Processors.Filters;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Defines extensions that allow the alteration of the lightness component of an
+ /// using Mutate/Clone.
+ ///
+ public static class LightnessExtensions
+ {
+ ///
+ /// Alters the lightness component of the image.
+ ///
+ ///
+ /// A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
+ /// Other values are linear multipliers on the effect. Values of an amount over 1 are allowed, providing lighter results.
+ ///
+ /// The image this method extends.
+ /// The proportion of the conversion. Must be greater than or equal to 0.
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext Lightness(this IImageProcessingContext source, float amount)
+ => source.ApplyProcessor(new LightnessProcessor(amount));
+
+ ///
+ /// Alters the lightness component of the image.
+ ///
+ ///
+ /// A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
+ /// Other values are linear multipliers on the effect. Values of an amount over 1 are allowed, providing lighter results.
+ ///
+ /// The image this method extends.
+ /// The proportion of the conversion. Must be greater than or equal to 0.
+ ///
+ /// The structure that specifies the portion of the image object to alter.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext Lightness(this IImageProcessingContext source, float amount, Rectangle rectangle)
+ => source.ApplyProcessor(new LightnessProcessor(amount), rectangle);
+ }
+}
diff --git a/src/ImageSharp/Processing/KnownFilterMatrices.cs b/src/ImageSharp/Processing/KnownFilterMatrices.cs
index 1f36e2593..31b19433c 100644
--- a/src/ImageSharp/Processing/KnownFilterMatrices.cs
+++ b/src/ImageSharp/Processing/KnownFilterMatrices.cs
@@ -432,6 +432,32 @@ namespace SixLabors.ImageSharp.Processing
return m;
}
+ ///
+ /// Create a lightness filter matrix using the given amount.
+ ///
+ ///
+ /// A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
+ /// Other values are linear multipliers on the effect. Values of an amount over 1 are allowed, providing lighter results.
+ ///
+ /// The proportion of the conversion. Must be greater than or equal to 0.
+ /// The
+ public static ColorMatrix CreateLightnessFilter(float amount)
+ {
+ Guard.MustBeGreaterThanOrEqualTo(amount, 0, nameof(amount));
+ amount--;
+
+ return new ColorMatrix
+ {
+ M11 = 1F,
+ M22 = 1F,
+ M33 = 1F,
+ M44 = 1F,
+ M51 = amount,
+ M52 = amount,
+ M53 = amount
+ };
+ }
+
///
/// Create a sepia filter matrix using the given amount.
/// The formula used matches the svg specification.
diff --git a/src/ImageSharp/Processing/Processors/Filters/LightnessProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/LightnessProcessor.cs
new file mode 100644
index 000000000..49be3b6a6
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/Filters/LightnessProcessor.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Processing.Processors.Filters
+{
+ ///
+ /// Applies a lightness filter matrix using the given amount.
+ ///
+ public sealed class LightnessProcessor : FilterProcessor
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
+ /// Other values are linear multipliers on the effect. Values of an amount over 1 are allowed, providing lighter results.
+ ///
+ /// The proportion of the conversion. Must be greater than or equal to 0.
+ public LightnessProcessor(float amount)
+ : base(KnownFilterMatrices.CreateLightnessFilter(amount))
+ {
+ this.Amount = amount;
+ }
+
+ ///
+ /// Gets the proportion of the conversion
+ ///
+ public float Amount { get; }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Processing/Filters/LightnessTest.cs b/tests/ImageSharp.Tests/Processing/Filters/LightnessTest.cs
new file mode 100644
index 000000000..29d1d63e6
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/Filters/LightnessTest.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Processing;
+using SixLabors.ImageSharp.Processing.Processors.Filters;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Effects
+{
+ public class LightnessTest : BaseImageOperationsExtensionTest
+ {
+ [Fact]
+ public void Lightness_amount_LightnessProcessorDefaultsSet()
+ {
+ this.operations.Lightness(.5F);
+ LightnessProcessor processor = this.Verify();
+
+ Assert.Equal(.5F, processor.Amount);
+ }
+
+ [Fact]
+ public void Lightness_amount_rect_LightnessProcessorDefaultsSet()
+ {
+ this.operations.Lightness(.5F, this.rect);
+ LightnessProcessor processor = this.Verify(this.rect);
+
+ Assert.Equal(.5F, processor.Amount);
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Filters/LightnessTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Filters/LightnessTest.cs
new file mode 100644
index 000000000..c330ed6d9
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/Processors/Filters/LightnessTest.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects
+{
+ using SixLabors.ImageSharp.Processing;
+ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+
+ [GroupOutput("Filters")]
+ public class LightnessTest
+ {
+ private readonly ImageComparer imageComparer = ImageComparer.Tolerant(0.007F);
+
+ public static readonly TheoryData LightnessValues
+ = new TheoryData
+ {
+ .5F,
+ 1.5F
+ };
+
+ [Theory]
+ [WithTestPatternImages(nameof(LightnessValues), 48, 48, PixelTypes.Rgba32)]
+ public void ApplyLightnessFilter(TestImageProvider provider, float value)
+ where TPixel : struct, IPixel => provider.RunValidatingProcessorTest(ctx => ctx.Lightness(value), value, this.imageComparer);
+ }
+}
diff --git a/tests/Images/External b/tests/Images/External
index 468e39ad2..58b2c01f9 160000
--- a/tests/Images/External
+++ b/tests/Images/External
@@ -1 +1 @@
-Subproject commit 468e39ad25c9c2f38d5a16d603ec09f11d1fe0a2
+Subproject commit 58b2c01f9b66dd42d2b5b040b85e6846083b5e5f