Browse Source

Fix Saturation, tweak Polaroid.

Former-commit-id: 70b09066081c21e2d2ea262c7bd9d3f5f4de6f4e
Former-commit-id: 7ed1e1227ad5198646dd07bf636b6dd141e1f521
Former-commit-id: 877b7c2fca734818e34ad024924d3b42b277d47f
af/merge-core
James Jackson-South 10 years ago
parent
commit
790f2925a8
  1. 11
      src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs
  2. 2
      src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs
  3. 56
      src/ImageProcessor/Filters/ColorMatrix/Saturation.cs
  4. 78
      src/ImageProcessor/Filters/Saturation.cs
  5. 6
      tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

11
src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs

@ -13,6 +13,13 @@ namespace ImageProcessor.Filters
/// </summary>
public class ColorMatrixFilter : ParallelImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="ColorMatrixFilter"/> class.
/// </summary>
public ColorMatrixFilter()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ColorMatrixFilter"/> class.
/// </summary>
@ -23,9 +30,9 @@ namespace ImageProcessor.Filters
}
/// <summary>
/// Gets the matrix value.
/// Gets or sets the matrix value.
/// </summary>
public Matrix4x4 Value { get; }
public Matrix4x4 Value { get; set; }
/// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)

2
src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs

@ -24,7 +24,7 @@ namespace ImageProcessor.Filters
M21 = -0.022f,
M22 = 1.578f,
M23 = -0.022f,
M31 = .616f,
M31 = .216f,
M32 = -.16f,
M33 = 1.5831f,
M41 = 0.02f,

56
src/ImageProcessor/Filters/ColorMatrix/Saturation.cs

@ -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;
}
}
}

78
src/ImageProcessor/Filters/Saturation.cs

@ -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);
}
}
}

6
tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

@ -16,15 +16,15 @@ namespace ImageProcessor.Tests
//{ "Brightness--50", new Brightness(-50) },
//{ "Contrast-50", new Contrast(50) },
//{ "Contrast--50", new Contrast(-50) },
//{ "Saturation-100", new Saturation(100) },
//{ "Saturation--0", new Saturation(0) },
{ "Saturation-50", new Saturation(50) },
{ "Saturation--50", new Saturation(-50) },
//{ "Alpha--50", new Alpha(50) },
//{ "Invert", new Invert() },
//{ "Sepia", new Sepia() },
//{ "BlackWhite", new BlackWhite() },
//{ "Lomograph", new Lomograph() },
//{ "Polaroid", new Polaroid() },
{ "Brownie", new Kodachrome() },
//{ "Kodachrome", new Kodachrome() },
//{ "GreyscaleBt709", new GreyscaleBt709() },
//{ "GreyscaleBt601", new GreyscaleBt601() },
};

Loading…
Cancel
Save