mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: 70b09066081c21e2d2ea262c7bd9d3f5f4de6f4e Former-commit-id: 7ed1e1227ad5198646dd07bf636b6dd141e1f521 Former-commit-id: 877b7c2fca734818e34ad024924d3b42b277d47faf/merge-core
5 changed files with 69 additions and 84 deletions
@ -0,0 +1,56 @@ |
|||
// <copyright file="Saturation.cs" company="James South">
|
|||
// Copyright (c) James South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessor.Filters |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor"/> to change the saturation of an <see cref="Image"/>.
|
|||
/// </summary>
|
|||
public class Saturation : ColorMatrixFilter |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Saturation"/> class.
|
|||
/// </summary>
|
|||
/// <param name="saturation">The new saturation of the image. Must be between -100 and 100.</param>
|
|||
/// <exception cref="ArgumentException">
|
|||
/// <paramref name="saturation"/> is less than -100 or is greater than 100.
|
|||
/// </exception>
|
|||
public Saturation(int saturation) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation)); |
|||
float saturationFactor = saturation / 100f; |
|||
|
|||
// Stop at -1 to prevent inversion.
|
|||
saturationFactor++; |
|||
|
|||
// The matrix is set up to "shear" the colour space using the following set of values.
|
|||
// Note that each colour component has an effective luminance which contributes to the
|
|||
// overall brightness of the pixel.
|
|||
// See http://graficaobscura.com/matrix/index.html
|
|||
float saturationComplement = 1.0f - saturationFactor; |
|||
float saturationComplementR = 0.3086f * saturationComplement; |
|||
float saturationComplementG = 0.6094f * saturationComplement; |
|||
float saturationComplementB = 0.0820f * saturationComplement; |
|||
|
|||
Matrix4x4 matrix = new Matrix4x4() |
|||
{ |
|||
M11 = saturationComplementR + saturationFactor, |
|||
M12 = saturationComplementR, |
|||
M13 = saturationComplementR, |
|||
M21 = saturationComplementG, |
|||
M22 = saturationComplementG + saturationFactor, |
|||
M23 = saturationComplementG, |
|||
M31 = saturationComplementB, |
|||
M32 = saturationComplementB, |
|||
M33 = saturationComplementB + saturationFactor, |
|||
}; |
|||
|
|||
this.Value = matrix; |
|||
} |
|||
} |
|||
} |
|||
@ -1,78 +0,0 @@ |
|||
// <copyright file="Saturation.cs" company="James South">
|
|||
// Copyright (c) James South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessor.Filters |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
|
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor"/> to change the saturation of an <see cref="Image"/>.
|
|||
/// </summary>
|
|||
public class Saturation : ParallelImageProcessor |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Saturation"/> class.
|
|||
/// </summary>
|
|||
/// <param name="saturation">The new saturation of the image. Must be between -100 and 100.</param>
|
|||
/// <exception cref="ArgumentException">
|
|||
/// <paramref name="saturation"/> is less than -100 or is greater than 100.
|
|||
/// </exception>
|
|||
public Saturation(int saturation) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation)); |
|||
this.Value = saturation; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the saturation value.
|
|||
/// </summary>
|
|||
public int Value { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
|||
{ |
|||
float saturation = this.Value / 100f; |
|||
int sourceY = sourceRectangle.Y; |
|||
int sourceBottom = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
|
|||
Parallel.For( |
|||
startY, |
|||
endY, |
|||
y => |
|||
{ |
|||
if (y >= sourceY && y < sourceBottom) |
|||
{ |
|||
for (int x = startX; x < endX; x++) |
|||
{ |
|||
target[x, y] = AdjustSaturation(source[x, y], saturation); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns a <see cref="Color"/> with the saturation adjusted.
|
|||
/// </summary>
|
|||
/// <param name="color">The source color.</param>
|
|||
/// <param name="saturation">The saturation adjustment factor.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Color"/>.
|
|||
/// </returns>
|
|||
private static Color AdjustSaturation(Color color, float saturation) |
|||
{ |
|||
//color = PixelOperations.ToLinear(color);
|
|||
|
|||
// TODO: This can be done with a matrix. But why can I not get conversion to work?
|
|||
Hsv hsv = color; |
|||
return new Hsv(hsv.H, saturation, hsv.V); |
|||
|
|||
//return PixelOperations.ToSrgb(newHsv);
|
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue