Browse Source

Refactor color matrix filters

Former-commit-id: 7b622188eba8ec35091a0950236a5078b76dd6e7
Former-commit-id: 132e0295dec2531d543f2d655f81351ac5989d3b
Former-commit-id: 22d0566ae5ef5412ec961b16e97d1ba3cbeb9900
af/merge-core
James Jackson-South 10 years ago
parent
commit
11aa02a368
  1. 14
      src/ImageProcessor/Filters/ColorMatrix/BlackWhite.cs
  2. 20
      src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs
  3. 14
      src/ImageProcessor/Filters/ColorMatrix/GreyscaleBt601.cs
  4. 14
      src/ImageProcessor/Filters/ColorMatrix/GreyscaleBt709.cs
  5. 14
      src/ImageProcessor/Filters/ColorMatrix/Kodachrome.cs
  6. 14
      src/ImageProcessor/Filters/ColorMatrix/Lomograph.cs
  7. 14
      src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs
  8. 25
      src/ImageProcessor/Filters/ColorMatrix/Saturation.cs
  9. 14
      src/ImageProcessor/Filters/ColorMatrix/Sepia.cs
  10. 178
      src/ImageProcessor/Filters/ImageFilterExtensions.cs

14
src/ImageProcessor/Filters/ColorMatrix/BlackWhite.cs

@ -12,10 +12,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class BlackWhite : ColorMatrixFilter public class BlackWhite : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The BlackWhite matrix. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = 1.5f, M11 = 1.5f,
M12 = 1.5f, M12 = 1.5f,
@ -30,13 +28,5 @@ namespace ImageProcessor.Filters
M42 = -1f, M42 = -1f,
M43 = -1f, M43 = -1f,
}; };
/// <summary>
/// Initializes a new instance of the <see cref="BlackWhite"/> class.
/// </summary>
public BlackWhite()
: base(ColorMatrix)
{
}
} }
} }

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

@ -11,26 +11,10 @@ namespace ImageProcessor.Filters
/// <summary> /// <summary>
/// The color matrix filter. /// The color matrix filter.
/// </summary> /// </summary>
public class ColorMatrixFilter : ParallelImageProcessor, IColorMatrixFilter public abstract class ColorMatrixFilter : ParallelImageProcessor, IColorMatrixFilter
{ {
/// <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>
/// <param name="matrix">The <see cref="Matrix4x4"/> to apply.</param>
public ColorMatrixFilter(Matrix4x4 matrix)
{
this.Matrix = matrix;
}
/// <inheritdoc/> /// <inheritdoc/>
public Matrix4x4 Matrix { get; set; } public abstract Matrix4x4 Matrix { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)

14
src/ImageProcessor/Filters/ColorMatrix/GreyscaleBt601.cs

@ -13,10 +13,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class GreyscaleBt601 : ColorMatrixFilter public class GreyscaleBt601 : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The greyscale matrix. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = .299f, M11 = .299f,
M12 = .299f, M12 = .299f,
@ -28,13 +26,5 @@ namespace ImageProcessor.Filters
M32 = .114f, M32 = .114f,
M33 = .114f M33 = .114f
}; };
/// <summary>
/// Initializes a new instance of the <see cref="GreyscaleBt601"/> class.
/// </summary>
public GreyscaleBt601()
: base(ColorMatrix)
{
}
} }
} }

14
src/ImageProcessor/Filters/ColorMatrix/GreyscaleBt709.cs

@ -13,10 +13,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class GreyscaleBt709 : ColorMatrixFilter public class GreyscaleBt709 : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The greyscale matrix. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = .2126f, M11 = .2126f,
M12 = .2126f, M12 = .2126f,
@ -28,13 +26,5 @@ namespace ImageProcessor.Filters
M32 = .0722f, M32 = .0722f,
M33 = .0722f M33 = .0722f
}; };
/// <summary>
/// Initializes a new instance of the <see cref="GreyscaleBt709"/> class.
/// </summary>
public GreyscaleBt709()
: base(ColorMatrix)
{
}
} }
} }

14
src/ImageProcessor/Filters/ColorMatrix/Kodachrome.cs

@ -12,10 +12,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class Kodachrome : ColorMatrixFilter public class Kodachrome : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The Kodachrome matrix. Purely artistic in composition. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = 0.6997023f, M11 = 0.6997023f,
M22 = 0.4609577f, M22 = 0.4609577f,
@ -24,13 +22,5 @@ namespace ImageProcessor.Filters
M42 = -0.005f, M42 = -0.005f,
M43 = 0.005f M43 = 0.005f
}; };
/// <summary>
/// Initializes a new instance of the <see cref="Kodachrome"/> class.
/// </summary>
public Kodachrome()
: base(ColorMatrix)
{
}
} }
} }

14
src/ImageProcessor/Filters/ColorMatrix/Lomograph.cs

@ -12,10 +12,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class Lomograph : ColorMatrixFilter public class Lomograph : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The Lomograph matrix. Purely artistic in composition. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = 1.5f, M11 = 1.5f,
M22 = 1.45f, M22 = 1.45f,
@ -24,13 +22,5 @@ namespace ImageProcessor.Filters
M42 = .0f, M42 = .0f,
M43 = -.08f M43 = -.08f
}; };
/// <summary>
/// Initializes a new instance of the <see cref="Lomograph"/> class.
/// </summary>
public Lomograph()
: base(ColorMatrix)
{
}
} }
} }

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

@ -12,10 +12,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class Polaroid : ColorMatrixFilter public class Polaroid : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The Polaroid matrix. Purely artistic in composition. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = 1.538f, M11 = 1.538f,
M12 = -0.062f, M12 = -0.062f,
@ -30,13 +28,5 @@ namespace ImageProcessor.Filters
M42 = -0.05f, M42 = -0.05f,
M43 = -0.05f M43 = -0.05f
}; };
/// <summary>
/// Initializes a new instance of the <see cref="Polaroid"/> class.
/// </summary>
public Polaroid()
: base(ColorMatrix)
{
}
} }
} }

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

@ -13,6 +13,16 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class Saturation : ColorMatrixFilter public class Saturation : ColorMatrixFilter
{ {
/// <summary>
/// The saturation to be applied to the image.
/// </summary>
private readonly int saturation;
/// <summary>
/// The <see cref="Matrix4x4"/> used to alter the image.
/// </summary>
private Matrix4x4 matrix;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Saturation"/> class. /// Initializes a new instance of the <see cref="Saturation"/> class.
/// </summary> /// </summary>
@ -23,7 +33,16 @@ namespace ImageProcessor.Filters
public Saturation(int saturation) public Saturation(int saturation)
{ {
Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation)); Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation));
float saturationFactor = saturation / 100f; this.saturation = saturation;
}
/// <inheritdoc/>
public override Matrix4x4 Matrix => this.matrix;
/// <inheritdoc/>
protected override void OnApply(Rectangle targetRectangle, Rectangle sourceRectangle)
{
float saturationFactor = this.saturation / 100f;
// Stop at -1 to prevent inversion. // Stop at -1 to prevent inversion.
saturationFactor++; saturationFactor++;
@ -37,7 +56,7 @@ namespace ImageProcessor.Filters
float saturationComplementG = 0.6094f * saturationComplement; float saturationComplementG = 0.6094f * saturationComplement;
float saturationComplementB = 0.0820f * saturationComplement; float saturationComplementB = 0.0820f * saturationComplement;
Matrix4x4 matrix = new Matrix4x4() Matrix4x4 matrix4X4 = new Matrix4x4()
{ {
M11 = saturationComplementR + saturationFactor, M11 = saturationComplementR + saturationFactor,
M12 = saturationComplementR, M12 = saturationComplementR,
@ -50,7 +69,7 @@ namespace ImageProcessor.Filters
M33 = saturationComplementB + saturationFactor, M33 = saturationComplementB + saturationFactor,
}; };
this.Matrix = matrix; this.matrix = matrix4X4;
} }
} }
} }

14
src/ImageProcessor/Filters/ColorMatrix/Sepia.cs

@ -12,10 +12,8 @@ namespace ImageProcessor.Filters
/// </summary> /// </summary>
public class Sepia : ColorMatrixFilter public class Sepia : ColorMatrixFilter
{ {
/// <summary> /// <inheritdoc/>
/// The sepia matrix. public override Matrix4x4 Matrix => new Matrix4x4()
/// </summary>
private static readonly Matrix4x4 ColorMatrix = new Matrix4x4()
{ {
M11 = .393f, M11 = .393f,
M12 = .349f, M12 = .349f,
@ -27,13 +25,5 @@ namespace ImageProcessor.Filters
M32 = .168f, M32 = .168f,
M33 = .131f M33 = .131f
}; };
/// <summary>
/// Initializes a new instance of the <see cref="Sepia"/> class.
/// </summary>
public Sepia()
: base(ColorMatrix)
{
}
} }
} }

178
src/ImageProcessor/Filters/ImageFilterExtensions.cs

@ -47,6 +47,69 @@ namespace ImageProcessor.Filters
return source.Process(source.Bounds, new Blend(image, percent)); return source.Process(source.Bounds, new Blend(image, percent));
} }
/// <summary>
/// Combines the given image together with the current one by blending their pixels.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="image">The image to blend with the currently processing image.</param>
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Blend(this Image source, ImageBase image, int percent, Rectangle rectangle)
{
return source.Process(rectangle, new Blend(image, percent));
}
/// <summary>
/// Applies black and white toning to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image BlackWhite(this Image source)
{
return BlackWhite(source, source.Bounds);
}
/// <summary>
/// Applies black and white toning to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image BlackWhite(this Image source, Rectangle rectangle)
{
return source.Process(rectangle, new BlackWhite());
}
/// <summary>
/// Alters the brightness component of the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Brightness(this Image source, int amount)
{
return Brightness(source, amount, source.Bounds);
}
/// <summary>
/// Alters the brightness component of the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Brightness(this Image source, int amount, Rectangle rectangle)
{
return source.Process(rectangle, new Brightness(amount));
}
/// <summary> /// <summary>
/// Alters the contrast component of the image. /// Alters the contrast component of the image.
/// </summary> /// </summary>
@ -72,6 +135,33 @@ namespace ImageProcessor.Filters
return source.Process(rectangle, new Contrast(amount)); return source.Process(rectangle, new Contrast(amount));
} }
/// <summary>
/// Applies greyscale toning to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="mode">The formula to apply to perform the operation.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709)
{
return Greyscale(source, source.Bounds, mode);
}
/// <summary>
/// Applies greyscale toning to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <param name="mode">The formula to apply to perform the operation.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709)
{
return mode == GreyscaleMode.Bt709
? source.Process(rectangle, new GreyscaleBt709())
: source.Process(rectangle, new GreyscaleBt601());
}
/// <summary> /// <summary>
/// Inverts the colors of the image. /// Inverts the colors of the image.
/// </summary> /// </summary>
@ -96,76 +186,120 @@ namespace ImageProcessor.Filters
} }
/// <summary> /// <summary>
/// Applies sepia toning to the image. /// Alters the colors of the image recreating an old Kodachrome camera effect.
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image Sepia(this Image source) public static Image Kodachrome(this Image source)
{ {
return Sepia(source, source.Bounds); return Kodachrome(source, source.Bounds);
} }
/// <summary> /// <summary>
/// Applies sepia toning to the image. /// Alters the colors of the image recreating an old Kodachrome camera effect.
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image Sepia(this Image source, Rectangle rectangle) public static Image Kodachrome(this Image source, Rectangle rectangle)
{ {
return source.Process(rectangle, new Sepia()); return source.Process(rectangle, new Kodachrome());
} }
/// <summary> /// <summary>
/// Applies black and white toning to the image. /// Alters the colors of the image recreating an old Lomograph camera effect.
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image BlackWhite(this Image source) public static Image Lomograph(this Image source)
{ {
return BlackWhite(source, source.Bounds); return Lomograph(source, source.Bounds);
} }
/// <summary> /// <summary>
/// Applies black and white toning to the image. /// Alters the colors of the image recreating an old Lomograph camera effect.
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image BlackWhite(this Image source, Rectangle rectangle) public static Image Lomograph(this Image source, Rectangle rectangle)
{ {
return source.Process(rectangle, new BlackWhite()); return source.Process(rectangle, new Lomograph());
} }
/// <summary> /// <summary>
/// Applies greyscale toning to the image. /// Alters the colors of the image recreating an old Polaroid camera effect.
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="mode">The formula to apply to perform the operation.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709) public static Image Polaroid(this Image source)
{ {
return Greyscale(source, source.Bounds, mode); return Polaroid(source, source.Bounds);
} }
/// <summary> /// <summary>
/// Applies greyscale toning to the image. /// Alters the colors of the image recreating an old Polaroid camera effect.
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="mode">The formula to apply to perform the operation.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709) public static Image Polaroid(this Image source, Rectangle rectangle)
{ {
return mode == GreyscaleMode.Bt709 return source.Process(rectangle, new Polaroid());
? source.Process(rectangle, new GreyscaleBt709()) }
: source.Process(rectangle, new GreyscaleBt601());
/// <summary>
/// Alters the saturation component of the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Saturation(this Image source, int amount)
{
return Saturation(source, amount, source.Bounds);
}
/// <summary>
/// Alters the saturation component of the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Saturation(this Image source, int amount, Rectangle rectangle)
{
return source.Process(rectangle, new Saturation(amount));
}
/// <summary>
/// Applies sepia toning to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Sepia(this Image source)
{
return Sepia(source, source.Bounds);
}
/// <summary>
/// Applies sepia toning to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Sepia(this Image source, Rectangle rectangle)
{
return source.Process(rectangle, new Sepia());
} }
} }
} }

Loading…
Cancel
Save