mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
110 changed files with 1797 additions and 1742 deletions
@ -0,0 +1,446 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// Provides extensions methods for the <see cref="Matrix4x4"/> struct
|
|||
/// </summary>
|
|||
public static class MatrixFilters |
|||
{ |
|||
/// <summary>
|
|||
/// Gets a filter recreating Achromatomaly (Color desensitivity) color blindness
|
|||
/// </summary>
|
|||
public static Matrix4x4 AchromatomalyFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = .618F, |
|||
M12 = .163F, |
|||
M13 = .163F, |
|||
M21 = .320F, |
|||
M22 = .775F, |
|||
M23 = .320F, |
|||
M31 = .062F, |
|||
M32 = .062F, |
|||
M33 = .516F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Achromatopsia (Monochrome) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 AchromatopsiaFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = .299F, |
|||
M12 = .299F, |
|||
M13 = .299F, |
|||
M21 = .587F, |
|||
M22 = .587F, |
|||
M23 = .587F, |
|||
M31 = .114F, |
|||
M32 = .114F, |
|||
M33 = .114F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Deuteranomaly (Green-Weak) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 DeuteranomalyFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.8F, |
|||
M12 = 0.258F, |
|||
M21 = 0.2F, |
|||
M22 = 0.742F, |
|||
M23 = 0.142F, |
|||
M33 = 0.858F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Deuteranopia (Green-Blind) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 DeuteranopiaFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.625F, |
|||
M12 = 0.7F, |
|||
M21 = 0.375F, |
|||
M22 = 0.3F, |
|||
M23 = 0.3F, |
|||
M33 = 0.7F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Protanomaly (Red-Weak) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 ProtanomalyFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.817F, |
|||
M12 = 0.333F, |
|||
M21 = 0.183F, |
|||
M22 = 0.667F, |
|||
M23 = 0.125F, |
|||
M33 = 0.875F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Protanopia (Red-Blind) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 ProtanopiaFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.567F, |
|||
M12 = 0.558F, |
|||
M21 = 0.433F, |
|||
M22 = 0.442F, |
|||
M23 = 0.242F, |
|||
M33 = 0.758F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Tritanomaly (Blue-Weak) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 TritanomalyFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.967F, |
|||
M21 = 0.33F, |
|||
M22 = 0.733F, |
|||
M23 = 0.183F, |
|||
M32 = 0.267F, |
|||
M33 = 0.817F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating Tritanopia (Blue-Blind) color blindness.
|
|||
/// </summary>
|
|||
public static Matrix4x4 TritanopiaFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.95F, |
|||
M21 = 0.05F, |
|||
M22 = 0.433F, |
|||
M23 = 0.475F, |
|||
M32 = 0.567F, |
|||
M33 = 0.525F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets an approximated black and white filter
|
|||
/// </summary>
|
|||
public static Matrix4x4 BlackWhiteFilter { get; } = new Matrix4x4() |
|||
{ |
|||
M11 = 1.5F, |
|||
M12 = 1.5F, |
|||
M13 = 1.5F, |
|||
M21 = 1.5F, |
|||
M22 = 1.5F, |
|||
M23 = 1.5F, |
|||
M31 = 1.5F, |
|||
M32 = 1.5F, |
|||
M33 = 1.5F, |
|||
M41 = -1F, |
|||
M42 = -1F, |
|||
M43 = -1F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating an old Kodachrome camera effect.
|
|||
/// </summary>
|
|||
public static Matrix4x4 KodachromeFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 0.7297023F, |
|||
M22 = 0.6109577F, |
|||
M33 = 0.597218F, |
|||
M41 = 0.105F, |
|||
M42 = 0.145F, |
|||
M43 = 0.155F, |
|||
M44 = 1 |
|||
} |
|||
|
|||
* CreateSaturateFilter(1.2F) * CreateContrastFilter(1.35F); |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating an old Lomograph camera effect.
|
|||
/// </summary>
|
|||
public static Matrix4x4 LomographFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 1.5F, |
|||
M22 = 1.45F, |
|||
M33 = 1.16F, |
|||
M41 = -.1F, |
|||
M42 = -.02F, |
|||
M43 = -.07F, |
|||
M44 = 1 |
|||
} |
|||
|
|||
* CreateSaturateFilter(1.1F) * CreateContrastFilter(1.33F); |
|||
|
|||
/// <summary>
|
|||
/// Gets a filter recreating an old Polaroid camera effect.
|
|||
/// </summary>
|
|||
public static Matrix4x4 PolaroidFilter { get; } = new Matrix4x4 |
|||
{ |
|||
M11 = 1.538F, |
|||
M12 = -0.062F, |
|||
M13 = -0.262F, |
|||
M21 = -0.022F, |
|||
M22 = 1.578F, |
|||
M23 = -0.022F, |
|||
M31 = .216F, |
|||
M32 = -.16F, |
|||
M33 = 1.5831F, |
|||
M41 = 0.02F, |
|||
M42 = -0.05F, |
|||
M43 = -0.05F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Create a brightness filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 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 brighter results.
|
|||
/// </remarks>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateBrightnessFilter(float amount) |
|||
{ |
|||
Guard.MustBeGreaterThanOrEqualTo(amount, 0, nameof(amount)); |
|||
|
|||
// See https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = amount, |
|||
M22 = amount, |
|||
M33 = amount, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a contrast filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value of 0 will create an image that is completely gray. 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 results with more contrast.
|
|||
/// </remarks>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateContrastFilter(float amount) |
|||
{ |
|||
Guard.MustBeGreaterThanOrEqualTo(amount, 0, nameof(amount)); |
|||
|
|||
// See https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
float contrast = (-.5F * amount) + .5F; |
|||
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = amount, |
|||
M22 = amount, |
|||
M33 = amount, |
|||
M41 = contrast, |
|||
M42 = contrast, |
|||
M43 = contrast, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a greyscale filter matrix using the given amount using the formula as specified by ITU-R Recommendation BT.601.
|
|||
/// <see href="https://en.wikipedia.org/wiki/Luma_%28video%29#Rec._601_luma_versus_Rec._709_luma_coefficients"/>
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateGrayscaleBt601Filter(float amount) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); |
|||
amount = 1F - amount; |
|||
|
|||
// https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = .299F + (.701F * amount), |
|||
M12 = .299F - (.299F * amount), |
|||
M13 = .299F - (.299F * amount), |
|||
M21 = .587F - (.587F * amount), |
|||
M22 = .587F + (.413F * amount), |
|||
M23 = .587F - (.587F * amount), |
|||
M31 = .114F - (.114F * amount), |
|||
M32 = .114F - (.114F * amount), |
|||
M33 = .114F + (.886F * amount), |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a greyscale filter matrix using the given amount using the formula as specified by ITU-R Recommendation BT.709.
|
|||
/// <see href="https://en.wikipedia.org/wiki/Rec._709#Luma_coefficients"/>
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateGrayscaleBt709Filter(float amount) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); |
|||
amount = 1F - amount; |
|||
|
|||
// https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = .2126F + (.7874F * amount), |
|||
M12 = .2126F - (.2126F * amount), |
|||
M13 = .2126F - (.2126F * amount), |
|||
M21 = .7152F - (.7152F * amount), |
|||
M22 = .7152F + (.2848F * amount), |
|||
M23 = .7152F - (.7152F * amount), |
|||
M31 = .0722F - (.0722F * amount), |
|||
M32 = .0722F - (.0722F * amount), |
|||
M33 = .0722F + (.9278F * amount), |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a hue filter matrix using the given angle in degrees.
|
|||
/// </summary>
|
|||
/// <param name="degrees">The angle of rotation in degrees.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateHueFilter(float degrees) |
|||
{ |
|||
// Wrap the angle round at 360.
|
|||
degrees = degrees % 360; |
|||
|
|||
// Make sure it's not negative.
|
|||
while (degrees < 0) |
|||
{ |
|||
degrees += 360; |
|||
} |
|||
|
|||
float radian = MathFExtensions.DegreeToRadian(degrees); |
|||
float cosRadian = MathF.Cos(radian); |
|||
float sinRadian = MathF.Sin(radian); |
|||
|
|||
// The matrix is set up to preserve the luminance of the image.
|
|||
// See http://graficaobscura.com/matrix/index.html
|
|||
// Number are taken from https://msdn.microsoft.com/en-us/library/jj192162(v=vs.85).aspx
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = .213F + (cosRadian * .787F) - (sinRadian * .213F), |
|||
M12 = .213F - (cosRadian * .213F) - (sinRadian * 0.143F), |
|||
M13 = .213F - (cosRadian * .213F) - (sinRadian * .787F), |
|||
M21 = .715F - (cosRadian * .715F) - (sinRadian * .715F), |
|||
M22 = .715F + (cosRadian * .285F) + (sinRadian * 0.140F), |
|||
M23 = .715F - (cosRadian * .715F) + (sinRadian * .715F), |
|||
M31 = .072F - (cosRadian * .072F) + (sinRadian * .928F), |
|||
M32 = .072F - (cosRadian * .072F) - (sinRadian * 0.283F), |
|||
M33 = .072F + (cosRadian * .928F) + (sinRadian * .072F), |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create an invert filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateInvertFilter(float amount) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); |
|||
|
|||
// See https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
float invert = 1F - (2F * amount); |
|||
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = invert, |
|||
M22 = invert, |
|||
M33 = invert, |
|||
M41 = amount, |
|||
M42 = amount, |
|||
M43 = amount, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create an opacity filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateOpacityFilter(float amount) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); |
|||
|
|||
// See https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = 1, |
|||
M22 = 1, |
|||
M33 = 1, |
|||
M44 = amount |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a saturation filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value of 0 is completely un-saturated. A value of 1 leaves the input unchanged.
|
|||
/// Other values are linear multipliers on the effect. Values of amount over 1 are allowed, providing super-saturated results
|
|||
/// </remarks>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateSaturateFilter(float amount) |
|||
{ |
|||
Guard.MustBeGreaterThanOrEqualTo(amount, 0, nameof(amount)); |
|||
|
|||
// See https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = .213F + (.787F * amount), |
|||
M12 = .213F - (.213F * amount), |
|||
M13 = .213F - (.213F * amount), |
|||
M21 = .715F - (.715F * amount), |
|||
M22 = .715F + (.285F * amount), |
|||
M23 = .715F - (.715F * amount), |
|||
M31 = 1F - ((.213F + (.787F * amount)) + (.715F - (.715F * amount))), |
|||
M32 = 1F - ((.213F - (.213F * amount)) + (.715F + (.285F * amount))), |
|||
M33 = 1F - ((.213F - (.213F * amount)) + (.715F - (.715F * amount))), |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a sepia filter matrix using the given amount.
|
|||
/// The formula used matches the svg specification. <see href="http://www.w3.org/TR/filter-effects/#sepiaEquivalent"/>
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
/// <returns>The <see cref="Matrix4x4"/></returns>
|
|||
public static Matrix4x4 CreateSepiaFilter(float amount) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); |
|||
amount = 1F - amount; |
|||
|
|||
// See https://cs.chromium.org/chromium/src/cc/paint/render_surface_filters.cc
|
|||
return new Matrix4x4 |
|||
{ |
|||
M11 = .393F + (.607F * amount), |
|||
M12 = .349F - (.349F * amount), |
|||
M13 = .272F - (.272F * amount), |
|||
M21 = .769F - (.769F * amount), |
|||
M22 = .686F + (.314F * amount), |
|||
M23 = .534F - (.534F * amount), |
|||
M31 = .189F - (.189F * amount), |
|||
M32 = .168F - (.168F * amount), |
|||
M33 = .131F + (.869F * amount), |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing.Processors; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TPixel}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Alters the saturation component of the image.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value of 0 is completely un-saturated. A value of 1 leaves the input unchanged.
|
|||
/// Other values are linear multipliers on the effect. Values of amount over 1 are allowed, providing super-saturated results
|
|||
/// </remarks>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|||
public static IImageProcessingContext<TPixel> Saturate<TPixel>(this IImageProcessingContext<TPixel> source, float amount) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
source.ApplyProcessor(new SaturateProcessor<TPixel>(amount)); |
|||
return source; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Alters the saturation component of the image.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value of 0 is completely un-saturated. A value of 1 leaves the input unchanged.
|
|||
/// Other values are linear multipliers on the effect. Values of amount over 1 are allowed, providing super-saturated results
|
|||
/// </remarks>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</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{TPixel}"/>.</returns>
|
|||
public static IImageProcessingContext<TPixel> Saturate<TPixel>(this IImageProcessingContext<TPixel> source, float amount, Rectangle rectangle) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
source.ApplyProcessor(new SaturateProcessor<TPixel>(amount), rectangle); |
|||
return source; |
|||
} |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image to their black and white equivalent.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class BlackWhiteProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4() |
|||
{ |
|||
M11 = 1.5F, |
|||
M12 = 1.5F, |
|||
M13 = 1.5F, |
|||
M21 = 1.5F, |
|||
M22 = 1.5F, |
|||
M23 = 1.5F, |
|||
M31 = 1.5F, |
|||
M32 = 1.5F, |
|||
M33 = 1.5F, |
|||
M41 = -1F, |
|||
M42 = -1F, |
|||
M43 = -1F, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class AchromatomalyProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = .618F, |
|||
M12 = .163F, |
|||
M13 = .163F, |
|||
M21 = .320F, |
|||
M22 = .775F, |
|||
M23 = .320F, |
|||
M31 = .062F, |
|||
M32 = .062F, |
|||
M33 = .516F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Compand => false; |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class AchromatopsiaProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = .299F, |
|||
M12 = .299F, |
|||
M13 = .299F, |
|||
M21 = .587F, |
|||
M22 = .587F, |
|||
M23 = .587F, |
|||
M31 = .114F, |
|||
M32 = .114F, |
|||
M33 = .114F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Compand => false; |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class ProtanomalyProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = 0.817F, |
|||
M12 = 0.333F, |
|||
M21 = 0.183F, |
|||
M22 = 0.667F, |
|||
M23 = 0.125F, |
|||
M33 = 0.875F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Compand => false; |
|||
} |
|||
} |
|||
@ -1,78 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// The color matrix filter. Inherit from this class to perform operation involving color matrices.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal abstract class ColorMatrixProcessor<TPixel> : ImageProcessor<TPixel>, IColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public abstract Matrix4x4 Matrix { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public virtual bool Compand { get; set; } = true; |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
Matrix4x4 matrix = this.Matrix; |
|||
bool compand = this.Compand; |
|||
|
|||
Parallel.For( |
|||
minY, |
|||
maxY, |
|||
configuration.ParallelOptions, |
|||
y => |
|||
{ |
|||
Span<TPixel> row = source.GetPixelRowSpan(y - startY); |
|||
|
|||
for (int x = minX; x < maxX; x++) |
|||
{ |
|||
ref TPixel pixel = ref row[x - startX]; |
|||
var vector = pixel.ToVector4(); |
|||
|
|||
if (compand) |
|||
{ |
|||
vector = vector.Expand(); |
|||
} |
|||
|
|||
vector = Vector4.Transform(vector, matrix); |
|||
pixel.PackFromVector4(compand ? vector.Compress() : vector); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image to Grayscale applying the formula as specified by ITU-R Recommendation BT.601
|
|||
/// <see href="https://en.wikipedia.org/wiki/Luma_%28video%29#Rec._601_luma_versus_Rec._709_luma_coefficients"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GrayscaleBt601Processor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = .299F, |
|||
M12 = .299F, |
|||
M13 = .299F, |
|||
M21 = .587F, |
|||
M22 = .587F, |
|||
M23 = .587F, |
|||
M31 = .114F, |
|||
M32 = .114F, |
|||
M33 = .114F, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image to Grayscale applying the formula as specified by ITU-R Recommendation BT.709
|
|||
/// <see href="https://en.wikipedia.org/wiki/Rec._709#Luma_coefficients"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GrayscaleBt709Processor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = .2126F, |
|||
M12 = .2126F, |
|||
M13 = .2126F, |
|||
M21 = .7152F, |
|||
M22 = .7152F, |
|||
M23 = .7152F, |
|||
M31 = .0722F, |
|||
M32 = .0722F, |
|||
M33 = .0722F, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
} |
|||
@ -1,77 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="ImageProcessor{TPixel}"/> to change the hue of an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class HueProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HueProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="angle">The new brightness of the image. Must be between -100 and 100.</param>
|
|||
public HueProcessor(float angle) |
|||
{ |
|||
// Wrap the angle round at 360.
|
|||
angle = angle % 360; |
|||
|
|||
// Make sure it's not negative.
|
|||
while (angle < 0) |
|||
{ |
|||
angle += 360; |
|||
} |
|||
|
|||
this.Angle = angle; |
|||
|
|||
float radians = MathFExtensions.DegreeToRadian(angle); |
|||
float cosradians = MathF.Cos(radians); |
|||
float sinradians = MathF.Sin(radians); |
|||
|
|||
float lumR = .213F; |
|||
float lumG = .715F; |
|||
float lumB = .072F; |
|||
|
|||
float oneMinusLumR = 1 - lumR; |
|||
float oneMinusLumG = 1 - lumG; |
|||
float oneMinusLumB = 1 - lumB; |
|||
|
|||
// The matrix is set up to preserve the luminance of the image.
|
|||
// See http://graficaobscura.com/matrix/index.html
|
|||
// Number are taken from https://msdn.microsoft.com/en-us/library/jj192162(v=vs.85).aspx
|
|||
var matrix4X4 = new Matrix4x4 |
|||
{ |
|||
M11 = lumR + (cosradians * oneMinusLumR) - (sinradians * lumR), |
|||
M12 = lumR - (cosradians * lumR) - (sinradians * 0.143F), |
|||
M13 = lumR - (cosradians * lumR) - (sinradians * oneMinusLumR), |
|||
M21 = lumG - (cosradians * lumG) - (sinradians * lumG), |
|||
M22 = lumG + (cosradians * oneMinusLumG) + (sinradians * 0.140F), |
|||
M23 = lumG - (cosradians * lumG) + (sinradians * lumG), |
|||
M31 = lumB - (cosradians * lumB) + (sinradians * oneMinusLumB), |
|||
M32 = lumB - (cosradians * lumB) - (sinradians * 0.283F), |
|||
M33 = lumB + (cosradians * oneMinusLumB) + (sinradians * lumB), |
|||
M44 = 1 |
|||
}; |
|||
|
|||
this.Matrix = matrix4X4; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the rotation value.
|
|||
/// </summary>
|
|||
public float Angle { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Compand => false; |
|||
} |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Encapsulates properties and methods for creating processors that utilize a matrix to
|
|||
/// alter the image pixels.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal interface IColorMatrixProcessor<TPixel> : IImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the <see cref="Matrix4x4"/> used to alter the image.
|
|||
/// </summary>
|
|||
Matrix4x4 Matrix { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a value indicating whether to compress or expand individual pixel color values on processing.
|
|||
/// </summary>
|
|||
bool Compand { get; set; } |
|||
} |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating an old Kodachrome camera effect.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class KodachromeProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = 0.6997023F, |
|||
M22 = 0.4609577F, |
|||
M33 = 0.397218F, |
|||
M41 = 0.005F, |
|||
M42 = -0.005F, |
|||
M43 = 0.005F, |
|||
M44 = 1 |
|||
}; |
|||
} |
|||
} |
|||
@ -1,66 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="ImageProcessor{TPixel}"/> to change the saturation of an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class SaturationProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SaturationProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="saturation">The new saturation of the image. Must be between -100 and 100.</param>
|
|||
/// <exception cref="System.ArgumentException">
|
|||
/// <paramref name="saturation"/> is less than -100 or is greater than 100.
|
|||
/// </exception>
|
|||
public SaturationProcessor(int saturation) |
|||
{ |
|||
this.Amount = 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 color space using the following set of values.
|
|||
// Note that each color 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; |
|||
|
|||
var matrix4X4 = new Matrix4x4 |
|||
{ |
|||
M11 = saturationComplementR + saturationFactor, |
|||
M12 = saturationComplementR, |
|||
M13 = saturationComplementR, |
|||
M21 = saturationComplementG, |
|||
M22 = saturationComplementG + saturationFactor, |
|||
M23 = saturationComplementG, |
|||
M31 = saturationComplementB, |
|||
M32 = saturationComplementB, |
|||
M33 = saturationComplementB + saturationFactor, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
this.Matrix = matrix4X4; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the amount to apply.
|
|||
/// </summary>
|
|||
public int Amount { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix { get; } |
|||
} |
|||
} |
|||
@ -1,35 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image to their sepia equivalent.
|
|||
/// The formula used matches the svg specification. <see href="http://www.w3.org/TR/filter-effects/#sepiaEquivalent"/>
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class SepiaProcessor<TPixel> : ColorMatrixProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public override Matrix4x4 Matrix => new Matrix4x4 |
|||
{ |
|||
M11 = .393F, |
|||
M12 = .349F, |
|||
M13 = .272F, |
|||
M21 = .769F, |
|||
M22 = .686F, |
|||
M23 = .534F, |
|||
M31 = .189F, |
|||
M32 = .168F, |
|||
M33 = .131F, |
|||
M44 = 1 |
|||
}; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Compand => false; |
|||
} |
|||
} |
|||
@ -1,81 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> to change the alpha component of an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class AlphaProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="AlphaProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="percent">The percentage to adjust the opacity of the image. Must be between 0 and 1.</param>
|
|||
/// <exception cref="System.ArgumentException">
|
|||
/// <paramref name="percent"/> is less than 0 or is greater than 1.
|
|||
/// </exception>
|
|||
public AlphaProcessor(float percent) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(percent, 0, 1, nameof(percent)); |
|||
this.Value = percent; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the alpha value.
|
|||
/// </summary>
|
|||
public float Value { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
var alphaVector = new Vector4(1, 1, 1, this.Value); |
|||
|
|||
Parallel.For( |
|||
minY, |
|||
maxY, |
|||
configuration.ParallelOptions, |
|||
y => |
|||
{ |
|||
Span<TPixel> row = source.GetPixelRowSpan(y - startY); |
|||
|
|||
for (int x = minX; x < maxX; x++) |
|||
{ |
|||
ref TPixel pixel = ref row[x - startX]; |
|||
pixel.PackFromVector4(pixel.ToVector4() * alphaVector); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,87 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> to change the brightness of an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class BrightnessProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BrightnessProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="brightness">The new brightness of the image. Must be between -100 and 100.</param>
|
|||
/// <exception cref="System.ArgumentException">
|
|||
/// <paramref name="brightness"/> is less than -100 or is greater than 100.
|
|||
/// </exception>
|
|||
public BrightnessProcessor(int brightness) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(brightness, -100, 100, nameof(brightness)); |
|||
this.Value = brightness; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the brightness value.
|
|||
/// </summary>
|
|||
public int Value { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
float brightness = this.Value / 100F; |
|||
|
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
Parallel.For( |
|||
minY, |
|||
maxY, |
|||
configuration.ParallelOptions, |
|||
y => |
|||
{ |
|||
Span<TPixel> row = source.GetPixelRowSpan(y - startY); |
|||
|
|||
for (int x = minX; x < maxX; x++) |
|||
{ |
|||
ref TPixel pixel = ref row[x - startX]; |
|||
|
|||
// TODO: Check this with other formats.
|
|||
Vector4 vector = pixel.ToVector4().Expand(); |
|||
Vector3 transformed = new Vector3(vector.X, vector.Y, vector.Z) + new Vector3(brightness); |
|||
vector = new Vector4(transformed, vector.W); |
|||
|
|||
pixel.PackFromVector4(vector.Compress()); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,89 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> to change the contrast of an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class ContrastProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ContrastProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="contrast">The new contrast of the image. Must be between -100 and 100.</param>
|
|||
/// <exception cref="System.ArgumentException">
|
|||
/// <paramref name="contrast"/> is less than -100 or is greater than 100.
|
|||
/// </exception>
|
|||
public ContrastProcessor(int contrast) |
|||
{ |
|||
Guard.MustBeBetweenOrEqualTo(contrast, -100, 100, nameof(contrast)); |
|||
this.Value = contrast; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the contrast value.
|
|||
/// </summary>
|
|||
public int Value { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
float contrast = (100F + this.Value) / 100F; |
|||
|
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
var contrastVector = new Vector4(contrast, contrast, contrast, 1); |
|||
var shiftVector = new Vector4(.5F, .5F, .5F, 1); |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
Parallel.For( |
|||
minY, |
|||
maxY, |
|||
configuration.ParallelOptions, |
|||
y => |
|||
{ |
|||
Span<TPixel> row = source.GetPixelRowSpan(y - startY); |
|||
|
|||
for (int x = minX; x < maxX; x++) |
|||
{ |
|||
ref TPixel pixel = ref row[x - startX]; |
|||
|
|||
Vector4 vector = pixel.ToVector4().Expand(); |
|||
vector -= shiftVector; |
|||
vector *= contrastVector; |
|||
vector += shiftVector; |
|||
|
|||
pixel.PackFromVector4(vector.Compress()); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -1,66 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> to invert the colors of an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class InvertProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
Vector3 inverseVector = Vector3.One; |
|||
|
|||
// Align start/end positions.
|
|||
int minX = Math.Max(0, startX); |
|||
int maxX = Math.Min(source.Width, endX); |
|||
int minY = Math.Max(0, startY); |
|||
int maxY = Math.Min(source.Height, endY); |
|||
|
|||
// Reset offset if necessary.
|
|||
if (minX > 0) |
|||
{ |
|||
startX = 0; |
|||
} |
|||
|
|||
if (minY > 0) |
|||
{ |
|||
startY = 0; |
|||
} |
|||
|
|||
Parallel.For( |
|||
minY, |
|||
maxY, |
|||
configuration.ParallelOptions, |
|||
y => |
|||
{ |
|||
Span<TPixel> row = source.GetPixelRowSpan(y - startY); |
|||
|
|||
for (int x = minX; x < maxX; x++) |
|||
{ |
|||
ref TPixel pixel = ref row[x - startX]; |
|||
|
|||
var vector = pixel.ToVector4(); |
|||
Vector3 vector3 = inverseVector - new Vector3(vector.X, vector.Y, vector.Z); |
|||
|
|||
pixel.PackFromVector4(new Vector4(vector3, vector.W)); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a black and white filter matrix to the image
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class BlackWhiteProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BlackWhiteProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
public BlackWhiteProcessor() |
|||
: base(MatrixFilters.BlackWhiteFilter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a brightness filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class BrightnessProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BrightnessProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 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 brighter results.
|
|||
/// </remarks>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
public BrightnessProcessor(float amount) |
|||
: base(MatrixFilters.CreateBrightnessFilter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class AchromatomalyProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="AchromatomalyProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
public AchromatomalyProcessor() |
|||
: base(MatrixFilters.AchromatomalyFilter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class AchromatopsiaProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="AchromatopsiaProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
public AchromatopsiaProcessor() |
|||
: base(MatrixFilters.AchromatopsiaFilter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the colors of the image recreating Protanomaly (Red-Weak) color blindness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class ProtanomalyProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ProtanomalyProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
public ProtanomalyProcessor() |
|||
: base(MatrixFilters.ProtanomalyFilter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a contrast filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class ContrastProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ContrastProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value of 0 will create an image that is completely gray. 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 results with more contrast.
|
|||
/// </remarks>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
public ContrastProcessor(float amount) |
|||
: base(MatrixFilters.CreateContrastFilter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.Helpers; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Provides methods that accept a <see cref="Matrix4x4"/> matrix to apply freeform filters to images.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class FilterProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="FilterProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="matrix">The matrix used to apply the image filter</param>
|
|||
public FilterProcessor(Matrix4x4 matrix) |
|||
{ |
|||
this.Matrix = matrix; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="Matrix4x4"/> used to apply the image filter.
|
|||
/// </summary>
|
|||
public Matrix4x4 Matrix { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); |
|||
int startY = interest.Y; |
|||
int endY = interest.Bottom; |
|||
int startX = interest.X; |
|||
int endX = interest.Right; |
|||
Matrix4x4 matrix = this.Matrix; |
|||
|
|||
Parallel.For( |
|||
startY, |
|||
endY, |
|||
configuration.ParallelOptions, |
|||
y => |
|||
{ |
|||
Span<TPixel> row = source.GetPixelRowSpan(y); |
|||
|
|||
for (int x = startX; x < endX; x++) |
|||
{ |
|||
ref TPixel pixel = ref row[x]; |
|||
var vector = Vector4.Transform(pixel.ToVector4(), matrix); |
|||
pixel.PackFromVector4(vector); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a greyscale filter matrix using the given amount and the formula as specified by ITU-R Recommendation BT.601
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GrayscaleBt601Processor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GrayscaleBt601Processor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
public GrayscaleBt601Processor(float amount) |
|||
: base(MatrixFilters.CreateGrayscaleBt601Filter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a greyscale filter matrix using the given amount and the formula as specified by ITU-R Recommendation BT.709
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GrayscaleBt709Processor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GrayscaleBt709Processor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
public GrayscaleBt709Processor(float amount) |
|||
: base(MatrixFilters.CreateGrayscaleBt709Filter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a hue filter matrix using the given angle of rotation in degrees
|
|||
/// </summary>
|
|||
internal class HueProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HueProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="degrees">The angle of rotation in degrees</param>
|
|||
public HueProcessor(float degrees) |
|||
: base(MatrixFilters.CreateHueFilter(degrees)) |
|||
{ |
|||
this.Degrees = degrees; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the angle of rotation in degrees
|
|||
/// </summary>
|
|||
public float Degrees { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a filter matrix that inverts the colors of an image
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class InvertProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InvertProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
public InvertProcessor(float amount) |
|||
: base(MatrixFilters.CreateInvertFilter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a filter matrix recreating an old Kodachrome camera effect matrix to the image
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class KodachromeProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="KodachromeProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
public KodachromeProcessor() |
|||
: base(MatrixFilters.KodachromeFilter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies an opacity filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class OpacityProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="OpacityProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
public OpacityProcessor(float amount) |
|||
: base(MatrixFilters.CreateOpacityFilter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a saturation filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class SaturateProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SaturateProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// A value of 0 is completely un-saturated. A value of 1 leaves the input unchanged.
|
|||
/// Other values are linear multipliers on the effect. Values of amount over 1 are allowed, providing super-saturated results
|
|||
/// </remarks>
|
|||
/// <param name="amount">The proportion of the conversion. Must be greater than or equal to 0.</param>
|
|||
public SaturateProcessor(float amount) |
|||
: base(MatrixFilters.CreateSaturateFilter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a sepia filter matrix using the given amount.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class SepiaProcessor<TPixel> : FilterProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="SepiaProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
|
|||
public SepiaProcessor(float amount) |
|||
: base(MatrixFilters.CreateSepiaFilter(amount)) |
|||
{ |
|||
this.Amount = amount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the proportion of the conversion
|
|||
/// </summary>
|
|||
public float Amount { get; } |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing.Processors; |
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Effects |
|||
{ |
|||
public class AlphaTest : BaseImageOperationsExtensionTest |
|||
{ |
|||
[Fact] |
|||
public void Alpha_amount_AlphaProcessorDefaultsSet() |
|||
{ |
|||
this.operations.Alpha(0.2f); |
|||
var processor = this.Verify<AlphaProcessor<Rgba32>>(); |
|||
|
|||
Assert.Equal(.2f, processor.Value); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Alpha_amount_rect_AlphaProcessorDefaultsSet() |
|||
{ |
|||
this.operations.Alpha(0.6f, this.rect); |
|||
var processor = this.Verify<AlphaProcessor<Rgba32>>(this.rect); |
|||
|
|||
Assert.Equal(.6f, processor.Value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.Processing; |
|||
using SixLabors.ImageSharp.Processing.Processors; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Filters |
|||
{ |
|||
public class FilterTest : BaseImageOperationsExtensionTest |
|||
{ |
|||
[Fact] |
|||
public void Filter_CorrectProcessor() |
|||
{ |
|||
this.operations.Filter(MatrixFilters.AchromatomalyFilter * MatrixFilters.CreateHueFilter(90F)); |
|||
FilterProcessor<Rgba32> p = this.Verify<FilterProcessor<Rgba32>>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Filter_rect_CorrectProcessor() |
|||
{ |
|||
this.operations.Filter(MatrixFilters.AchromatomalyFilter * MatrixFilters.CreateHueFilter(90F), this.rect); |
|||
FilterProcessor<Rgba32> p = this.Verify<FilterProcessor<Rgba32>>(this.rect); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.Processing.Processors; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Effects |
|||
{ |
|||
public class OpacityTest : BaseImageOperationsExtensionTest |
|||
{ |
|||
[Fact] |
|||
public void Alpha_amount_AlphaProcessorDefaultsSet() |
|||
{ |
|||
this.operations.Opacity(0.2f); |
|||
OpacityProcessor<Rgba32> processor = this.Verify<OpacityProcessor<Rgba32>>(); |
|||
|
|||
Assert.Equal(.2f, processor.Amount); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Alpha_amount_rect_AlphaProcessorDefaultsSet() |
|||
{ |
|||
this.operations.Opacity(0.6f, this.rect); |
|||
OpacityProcessor<Rgba32> processor = this.Verify<OpacityProcessor<Rgba32>>(this.rect); |
|||
|
|||
Assert.Equal(.6f, processor.Amount); |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class BlackWhiteTest : FileTestBase |
|||
{ |
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyBlackWhiteFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.BlackWhite()); |
|||
image.DebugSave(provider); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyBlackWhiteFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.BlackWhite(bounds)); |
|||
image.DebugSave(provider); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,57 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class ColorBlindnessTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<ColorBlindness> ColorBlindnessFilters |
|||
= new TheoryData<ColorBlindness> |
|||
{ |
|||
ColorBlindness.Achromatomaly, |
|||
ColorBlindness.Achromatopsia, |
|||
ColorBlindness.Deuteranomaly, |
|||
ColorBlindness.Deuteranopia, |
|||
ColorBlindness.Protanomaly, |
|||
ColorBlindness.Protanopia, |
|||
ColorBlindness.Tritanomaly, |
|||
ColorBlindness.Tritanopia |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(ColorBlindnessFilters), DefaultPixelType)] |
|||
public void ImageShouldApplyColorBlindnessFilter<TPixel>(TestImageProvider<TPixel> provider, ColorBlindness colorBlindness) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.ColorBlindness(colorBlindness)); |
|||
image.DebugSave(provider, colorBlindness.ToString()); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(ColorBlindnessFilters), DefaultPixelType)] |
|||
public void ImageShouldApplyColorBlindnessFilterInBox<TPixel>(TestImageProvider<TPixel> provider, ColorBlindness colorBlindness) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.ColorBlindness(colorBlindness, bounds)); |
|||
image.DebugSave(provider, colorBlindness.ToString()); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,63 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class GrayscaleTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<GrayscaleMode> GrayscaleModeTypes |
|||
= new TheoryData<GrayscaleMode> |
|||
{ |
|||
GrayscaleMode.Bt601, |
|||
GrayscaleMode.Bt709 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Use test patterns over loaded images to save decode time.
|
|||
/// </summary>
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(GrayscaleModeTypes), 50, 50, DefaultPixelType)] |
|||
public void ImageShouldApplyGrayscaleFilterAll<TPixel>(TestImageProvider<TPixel> provider, GrayscaleMode value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Grayscale(value)); |
|||
var rgb = default(Rgb24); |
|||
System.Span<TPixel> span = image.Frames.RootFrame.GetPixelSpan(); |
|||
for (int i = 0; i < span.Length; i++) |
|||
{ |
|||
span[i].ToRgb24(ref rgb); |
|||
Assert.Equal(rgb.R, rgb.B); |
|||
Assert.Equal(rgb.B, rgb.G); |
|||
} |
|||
|
|||
image.DebugSave(provider, value.ToString()); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(GrayscaleModeTypes), 50, 50, DefaultPixelType)] |
|||
public void ImageShouldApplyGrayscaleFilterInBox<TPixel>(TestImageProvider<TPixel> provider, GrayscaleMode value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (Image<TPixel> image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); |
|||
image.Mutate(x => x.Grayscale(value, bounds)); |
|||
image.DebugSave(provider, value.ToString()); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,50 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class HueTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<int> HueValues |
|||
= new TheoryData<int> |
|||
{ |
|||
180, |
|||
-180 |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(HueValues), DefaultPixelType)] |
|||
public void ImageShouldApplyHueFilter<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Hue(value)); |
|||
image.DebugSave(provider, value); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(HueValues), DefaultPixelType)] |
|||
public void ImageShouldApplyHueFilterInBox<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Hue(value, bounds)); |
|||
image.DebugSave(provider, value); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class KodachromeTest : FileTestBase |
|||
{ |
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyKodachromeFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Kodachrome()); |
|||
image.DebugSave(provider); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyKodachromeFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Kodachrome(bounds)); |
|||
image.DebugSave(provider); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class LomographTest : FileTestBase |
|||
{ |
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyLomographFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Lomograph()); |
|||
image.DebugSave(provider); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyLomographFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Lomograph(bounds)); |
|||
image.DebugSave(provider); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class PolaroidTest : FileTestBase |
|||
{ |
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyPolaroidFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Polaroid()); |
|||
image.DebugSave(provider); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyPolaroidFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Polaroid(bounds)); |
|||
image.DebugSave(provider); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,50 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class SaturationTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<int> SaturationValues |
|||
= new TheoryData<int> |
|||
{ |
|||
50 , |
|||
-50 , |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(SaturationValues), DefaultPixelType)] |
|||
public void ImageShouldApplySaturationFilter<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Saturation(value)); |
|||
image.DebugSave(provider, value); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(SaturationValues), DefaultPixelType)] |
|||
public void ImageShouldApplySaturationFilterInBox<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Saturation(value, bounds)); |
|||
image.DebugSave(provider, value); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.ColorMatrix |
|||
{ |
|||
public class SepiaTest : FileTestBase |
|||
{ |
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplySepiaFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Sepia()); |
|||
image.DebugSave(provider); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplySepiaFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Sepia(bounds)); |
|||
image.DebugSave(provider); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,50 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects |
|||
{ |
|||
public class AlphaTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<float> AlphaValues |
|||
= new TheoryData<float> |
|||
{ |
|||
20/100F, |
|||
80/100F |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(AlphaValues), DefaultPixelType)] |
|||
public void ImageShouldApplyAlphaFilter<TPixel>(TestImageProvider<TPixel> provider, float value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Alpha(value)); |
|||
image.DebugSave(provider, value); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(AlphaValues), DefaultPixelType)] |
|||
public void ImageShouldApplyAlphaFilterInBox<TPixel>(TestImageProvider<TPixel> provider, float value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Alpha(value, bounds)); |
|||
image.DebugSave(provider, value); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,50 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects |
|||
{ |
|||
public class BrightnessTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<int> BrightnessValues |
|||
= new TheoryData<int> |
|||
{ |
|||
50, |
|||
-50 |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(BrightnessValues), DefaultPixelType)] |
|||
public void ImageShouldApplyBrightnessFilter<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Brightness(value)); |
|||
image.DebugSave(provider, value); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(BrightnessValues), DefaultPixelType)] |
|||
public void ImageShouldApplyBrightnessFilterInBox<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Brightness(value, bounds)); |
|||
image.DebugSave(provider, value); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,50 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects |
|||
{ |
|||
public class ContrastTest : FileTestBase |
|||
{ |
|||
public static readonly TheoryData<int> ContrastValues |
|||
= new TheoryData<int> |
|||
{ |
|||
50, |
|||
-50 |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(ContrastValues), DefaultPixelType)] |
|||
public void ImageShouldApplyContrastFilter<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Contrast(value)); |
|||
image.DebugSave(provider, value); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), nameof(ContrastValues), DefaultPixelType)] |
|||
public void ImageShouldApplyContrastFilterInBox<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Contrast(value, bounds)); |
|||
image.DebugSave(provider, value); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects |
|||
{ |
|||
public class InvertTest : FileTestBase |
|||
{ |
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyInvertFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> image = provider.GetImage()) |
|||
{ |
|||
image.Mutate(x => x.Invert()); |
|||
image.DebugSave(provider); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFileCollection(nameof(DefaultFiles), DefaultPixelType)] |
|||
public void ImageShouldApplyInvertFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (Image<TPixel> source = provider.GetImage()) |
|||
using (var image = source.Clone()) |
|||
{ |
|||
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2); |
|||
|
|||
image.Mutate(x => x.Invert(bounds)); |
|||
image.DebugSave(provider); |
|||
|
|||
ImageComparer.Tolerant().VerifySimilarityIgnoreRegion(source, image, bounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class BlackWhiteTest |
|||
{ |
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyBlackWhiteFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(ctx => ctx.BlackWhite()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// 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 |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class BrightnessTest |
|||
{ |
|||
public static readonly TheoryData<float> BrightnessValues |
|||
= new TheoryData<float> |
|||
{ |
|||
.5F, |
|||
1.5F |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(BrightnessValues), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyBrightnessFilter<TPixel>(TestImageProvider<TPixel> provider, float value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(ctx => ctx.Brightness(value), value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing; |
|||
|
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class ColorBlindnessTest |
|||
{ |
|||
public static readonly TheoryData<ColorBlindness> ColorBlindnessFilters |
|||
= new TheoryData<ColorBlindness> |
|||
{ |
|||
ColorBlindness.Achromatomaly, |
|||
ColorBlindness.Achromatopsia, |
|||
ColorBlindness.Deuteranomaly, |
|||
ColorBlindness.Deuteranopia, |
|||
ColorBlindness.Protanomaly, |
|||
ColorBlindness.Protanopia, |
|||
ColorBlindness.Tritanomaly, |
|||
ColorBlindness.Tritanopia |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(ColorBlindnessFilters), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyColorBlindnessFilter<TPixel>(TestImageProvider<TPixel> provider, ColorBlindness colorBlindness) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.ColorBlindness(colorBlindness), colorBlindness.ToString()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// 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 |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class ContrastTest |
|||
{ |
|||
public static readonly TheoryData<float> ContrastValues |
|||
= new TheoryData<float> |
|||
{ |
|||
.5F, |
|||
1.5F |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(ContrastValues), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyContrastFilter<TPixel>(TestImageProvider<TPixel> provider, float value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Contrast(value), value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; |
|||
|
|||
using SixLabors.Primitives; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class FilterTest |
|||
{ |
|||
// Testing the generic FilterProcessor with more than one pixel type intentionally.
|
|||
// There is no need to do this with the specialized ones.
|
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32 | PixelTypes.Bgra32)] |
|||
public void ApplyFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
Matrix4x4 m = CreateCombinedTestFilterMatrix(); |
|||
|
|||
provider.RunValidatingProcessorTest(x => x.Filter(m)); |
|||
} |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyFilterInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
Matrix4x4 m = CreateCombinedTestFilterMatrix(); |
|||
|
|||
provider.RunRectangleConstrainedValidatingProcessorTest((x, b) => x.Filter(m, b)); |
|||
} |
|||
|
|||
private static Matrix4x4 CreateCombinedTestFilterMatrix() |
|||
{ |
|||
Matrix4x4 brightness = MatrixFilters.CreateBrightnessFilter(0.9F); |
|||
Matrix4x4 hue = MatrixFilters.CreateHueFilter(180F); |
|||
Matrix4x4 saturation = MatrixFilters.CreateSaturateFilter(1.5F); |
|||
Matrix4x4 m = brightness * hue * saturation; |
|||
return m; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing; |
|||
|
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class GrayscaleTest |
|||
{ |
|||
public static readonly TheoryData<GrayscaleMode> GrayscaleModeTypes |
|||
= new TheoryData<GrayscaleMode> |
|||
{ |
|||
GrayscaleMode.Bt601, |
|||
GrayscaleMode.Bt709 |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Use test patterns over loaded images to save decode time.
|
|||
/// </summary>
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(GrayscaleModeTypes), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyGrayscaleFilter<TPixel>(TestImageProvider<TPixel> provider, GrayscaleMode value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Grayscale(value), value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class HueTest |
|||
{ |
|||
public static readonly TheoryData<int> HueValues |
|||
= new TheoryData<int> |
|||
{ |
|||
180, |
|||
-180 |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(HueValues), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyHueFilter<TPixel>(TestImageProvider<TPixel> provider, int value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Hue(value), value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// 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 |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class InvertTest |
|||
{ |
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyInvertFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Invert()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class KodachromeTest |
|||
{ |
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyKodachromeFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Kodachrome()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class LomographTest |
|||
{ |
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyLomographFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Lomograph()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// 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 |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class OpacityTest |
|||
{ |
|||
public static readonly TheoryData<float> AlphaValues |
|||
= new TheoryData<float> |
|||
{ |
|||
20/100F, |
|||
80/100F |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(AlphaValues), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyAlphaFilter<TPixel>(TestImageProvider<TPixel> provider, float value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Opacity(value), value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class PolaroidTest |
|||
{ |
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplyPolaroidFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Polaroid()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class SaturateTest |
|||
{ |
|||
public static readonly TheoryData<float> SaturationValues |
|||
= new TheoryData<float> |
|||
{ |
|||
.5F, |
|||
1.5F, |
|||
}; |
|||
|
|||
[Theory] |
|||
[WithTestPatternImages(nameof(SaturationValues), 48, 48, PixelTypes.Rgba32)] |
|||
public void ApplySaturationFilter<TPixel>(TestImageProvider<TPixel> provider, float value) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Saturate(value), value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// 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.Filters |
|||
{ |
|||
[GroupOutput("Filters")] |
|||
public class SepiaTest |
|||
{ |
|||
[Theory] |
|||
[WithTestPatternImages(48, 48, PixelTypes.Rgba32)] |
|||
public void ApplySepiaFilter<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest(x => x.Sepia()); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue