mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: 4ea90489cba68da7b0ad07768a669db176d2bc2d Former-commit-id: 91e96abdcb9a5efef4a2af02e3766d48be8e75e4 Former-commit-id: c9a452193efb87b72082943580513cbaa8247db0pull/1/head
110 changed files with 2531 additions and 2204 deletions
@ -1,63 +1,52 @@ |
|||||
// <copyright file="Alpha.cs" company="James Jackson-South">
|
// <copyright file="Alpha.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System; |
using Processors; |
||||
using System.Numerics; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// An <see cref="IImageProcessor"/> to change the Alpha of an <see cref="Image"/>.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Alpha : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Alpha"/> class.
|
/// Alters the alpha component of the image.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="percent">The percentage to adjust the opacity of the image. Must be between 0 and 100.</param>
|
/// <param name="source">The image this method extends.</param>
|
||||
/// <exception cref="ArgumentException">
|
/// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param>
|
||||
/// <paramref name="percent"/> is less than 0 or is greater than 100.
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
/// </exception>
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
public Alpha(int percent) |
public static Image Alpha(this Image source, int percent, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
Guard.MustBeBetweenOrEqualTo(percent, 0, 100, nameof(percent)); |
return Alpha(source, percent, source.Bounds, progressHandler); |
||||
this.Value = percent; |
|
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the alpha value.
|
/// Alters the alpha component of the image.
|
||||
/// </summary>
|
/// </summary>
|
||||
public int Value { get; } |
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param>
|
||||
/// <inheritdoc/>
|
/// <param name="rectangle">
|
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Alpha(this Image source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
float alpha = this.Value / 100f; |
AlphaProcessor processor = new AlphaProcessor(percent); |
||||
int sourceY = sourceRectangle.Y; |
processor.OnProgress += progressHandler; |
||||
int sourceBottom = sourceRectangle.Bottom; |
|
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
|
||||
Vector4 alphaVector = new Vector4(1, 1, 1, alpha); |
|
||||
|
|
||||
Parallel.For( |
try |
||||
startY, |
{ |
||||
endY, |
return source.Process(rectangle, processor); |
||||
y => |
} |
||||
{ |
finally |
||||
if (y >= sourceY && y < sourceBottom) |
{ |
||||
{ |
processor.OnProgress -= progressHandler; |
||||
for (int x = startX; x < endX; x++) |
} |
||||
{ |
|
||||
Vector4 color = Color.ToNonPremultiplied(source[x, y]).ToVector4(); |
|
||||
color *= alphaVector; |
|
||||
target[x, y] = Color.FromNonPremultiplied(new Color(color)); |
|
||||
} |
|
||||
this.OnRowProcessed(); |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -1,73 +1,37 @@ |
|||||
// <copyright file="BackgroundColor.cs" company="James Jackson-South">
|
// <copyright file="BackgroundColor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System; |
using Processors; |
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Sets the background color of the image.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class BackgroundColor : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The epsilon for comparing floating point numbers.
|
/// Combines the given image together with the current one by blending their pixels.
|
||||
/// </summary>
|
/// </summary>
|
||||
private const float Epsilon = 0.001f; |
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color to set as the background.</param>
|
||||
/// <summary>
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
/// Initializes a new instance of the <see cref="BackgroundColor"/> class.
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
/// </summary>
|
public static Image BackgroundColor(this Image source, Color color, ProgressEventHandler progressHandler = null) |
||||
/// <param name="color">The <see cref="Color"/> to set the background color to.</param>
|
|
||||
public BackgroundColor(Color color) |
|
||||
{ |
{ |
||||
this.Value = Color.FromNonPremultiplied(color); |
BackgroundColorProcessor processor = new BackgroundColorProcessor(color); |
||||
} |
processor.OnProgress += progressHandler; |
||||
|
|
||||
/// <summary>
|
try |
||||
/// Gets the background color value.
|
{ |
||||
/// </summary>
|
return source.Process(source.Bounds, processor); |
||||
public Color Value { get; } |
} |
||||
|
finally |
||||
/// <inheritdoc/>
|
{ |
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
processor.OnProgress -= progressHandler; |
||||
{ |
} |
||||
int sourceY = sourceRectangle.Y; |
|
||||
int sourceBottom = sourceRectangle.Bottom; |
|
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
|
||||
Color backgroundColor = this.Value; |
|
||||
|
|
||||
Parallel.For( |
|
||||
startY, |
|
||||
endY, |
|
||||
y => |
|
||||
{ |
|
||||
if (y >= sourceY && y < sourceBottom) |
|
||||
{ |
|
||||
for (int x = startX; x < endX; x++) |
|
||||
{ |
|
||||
Color color = source[x, y]; |
|
||||
float a = color.A; |
|
||||
|
|
||||
if (a < 1 && a > 0) |
|
||||
{ |
|
||||
color = Color.Lerp(color, backgroundColor, .5f); |
|
||||
} |
|
||||
|
|
||||
if (Math.Abs(a) < Epsilon) |
|
||||
{ |
|
||||
color = backgroundColor; |
|
||||
} |
|
||||
|
|
||||
target[x, y] = color; |
|
||||
} |
|
||||
this.OnRowProcessed(); |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,50 @@ |
|||||
|
// <copyright file="BlackWhite.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies black and white toning to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image BlackWhite(this Image source, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return BlackWhite(source, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies black and white toning to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image BlackWhite(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
BlackWhiteProcessor processor = new BlackWhiteProcessor(); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,81 +1,60 @@ |
|||||
// <copyright file="Blend.cs" company="James Jackson-South">
|
// <copyright file="Blend.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System.Threading.Tasks; |
using Processors; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Combines two images together by blending the pixels.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Blend : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The image to blend.
|
/// Combines the given image together with the current one by blending their pixels.
|
||||
/// </summary>
|
|
||||
private readonly ImageBase toBlend; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Blend"/> class.
|
|
||||
/// </summary>
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
/// <param name="image">
|
/// <param name="image">
|
||||
/// The image to blend with the currently processing image.
|
/// The image to blend with the currently processing image.
|
||||
/// Disposal of this image is the responsibility of the developer.
|
/// Disposal of this image is the responsibility of the developer.
|
||||
/// </param>
|
/// </param>
|
||||
/// <param name="alpha">The opacity of the image to blend. Between 0 and 100.</param>
|
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
|
||||
public Blend(ImageBase image, int alpha = 100) |
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Blend(this Image source, ImageBase image, int percent = 50, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha)); |
return Blend(source, image, percent, source.Bounds, progressHandler); |
||||
this.toBlend = image; |
|
||||
this.Value = alpha; |
|
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the alpha percentage value.
|
/// Combines the given image together with the current one by blending their pixels.
|
||||
/// </summary>
|
/// </summary>
|
||||
public int Value { get; } |
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="image">
|
||||
/// <inheritdoc/>
|
/// The image to blend with the currently processing image.
|
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
/// Disposal of this image is the responsibility of the developer.
|
||||
|
/// </param>
|
||||
|
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Blend(this Image source, ImageBase image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
int sourceY = sourceRectangle.Y; |
BlendProcessor processor = new BlendProcessor(image, percent); |
||||
int sourceBottom = sourceRectangle.Bottom; |
processor.OnProgress += progressHandler; |
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
try |
||||
Rectangle bounds = this.toBlend.Bounds; |
{ |
||||
float alpha = this.Value / 100f; |
return source.Process(rectangle, processor); |
||||
|
} |
||||
Parallel.For( |
finally |
||||
startY, |
{ |
||||
endY, |
processor.OnProgress -= progressHandler; |
||||
y => |
} |
||||
{ |
|
||||
if (y >= sourceY && y < sourceBottom) |
|
||||
{ |
|
||||
for (int x = startX; x < endX; x++) |
|
||||
{ |
|
||||
Color color = source[x, y]; |
|
||||
|
|
||||
if (bounds.Contains(x, y)) |
|
||||
{ |
|
||||
Color blendedColor = this.toBlend[x, y]; |
|
||||
|
|
||||
if (blendedColor.A > 0) |
|
||||
{ |
|
||||
// Lerping colors is dependent on the alpha of the blended color
|
|
||||
float alphaFactor = alpha > 0 ? alpha : blendedColor.A; |
|
||||
color = Color.Lerp(color, blendedColor, alphaFactor); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
target[x, y] = color; |
|
||||
} |
|
||||
|
|
||||
this.OnRowProcessed(); |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,52 @@ |
|||||
|
// <copyright file="BoxBlur.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies a box blur to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image BoxBlur(this Image source, int radius = 7, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return BoxBlur(source, radius, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies a box blur to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image BoxBlur(this Image source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
BoxBlurProcessor processor = new BoxBlurProcessor(radius); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,65 +1,52 @@ |
|||||
// <copyright file="Brightness.cs" company="James Jackson-South">
|
// <copyright file="Brightness.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System; |
using Processors; |
||||
using System.Numerics; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// An <see cref="IImageProcessor"/> to change the brightness of an <see cref="Image"/>.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Brightness : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Brightness"/> class.
|
/// Alters the brightness component of the image.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="brightness">The new brightness of the image. Must be between -100 and 100.</param>
|
/// <param name="source">The image this method extends.</param>
|
||||
/// <exception cref="ArgumentException">
|
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
|
||||
/// <paramref name="brightness"/> is less than -100 or is greater than 100.
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
/// </exception>
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
public Brightness(int brightness) |
public static Image Brightness(this Image source, int amount, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
Guard.MustBeBetweenOrEqualTo(brightness, -100, 100, nameof(brightness)); |
return Brightness(source, amount, source.Bounds, progressHandler); |
||||
this.Value = brightness; |
|
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the brightness value.
|
/// Alters the brightness component of the image.
|
||||
/// </summary>
|
/// </summary>
|
||||
public int Value { get; } |
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
|
||||
/// <inheritdoc/>
|
/// <param name="rectangle">
|
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Brightness(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
float brightness = this.Value / 100f; |
BrightnessProcessor processor = new BrightnessProcessor(amount); |
||||
int sourceY = sourceRectangle.Y; |
processor.OnProgress += progressHandler; |
||||
int sourceBottom = sourceRectangle.Bottom; |
|
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
|
||||
|
|
||||
Parallel.For( |
|
||||
startY, |
|
||||
endY, |
|
||||
y => |
|
||||
{ |
|
||||
if (y >= sourceY && y < sourceBottom) |
|
||||
{ |
|
||||
for (int x = startX; x < endX; x++) |
|
||||
{ |
|
||||
Color color = Color.Expand(source[x, y]); |
|
||||
|
|
||||
Vector3 vector3 = color.ToVector3(); |
|
||||
vector3 += new Vector3(brightness); |
|
||||
|
|
||||
target[x, y] = Color.Compress(new Color(vector3, color.A)); |
try |
||||
} |
{ |
||||
this.OnRowProcessed(); |
return source.Process(rectangle, processor); |
||||
} |
} |
||||
}); |
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,88 @@ |
|||||
|
// <copyright file="ColorBlindness.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies the given colorblindness simulator to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies the given colorblindness simulator to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
IImageProcessor processor; |
||||
|
|
||||
|
switch (colorBlindness) |
||||
|
{ |
||||
|
case ImageProcessorCore.ColorBlindness.Achromatomaly: |
||||
|
processor = new AchromatomalyProcessor(); |
||||
|
break; |
||||
|
|
||||
|
case ImageProcessorCore.ColorBlindness.Achromatopsia: |
||||
|
processor = new AchromatopsiaProcessor(); |
||||
|
break; |
||||
|
|
||||
|
case ImageProcessorCore.ColorBlindness.Deuteranomaly: |
||||
|
processor = new DeuteranomalyProcessor(); |
||||
|
break; |
||||
|
|
||||
|
case ImageProcessorCore.ColorBlindness.Deuteranopia: |
||||
|
processor = new DeuteranopiaProcessor(); |
||||
|
break; |
||||
|
|
||||
|
case ImageProcessorCore.ColorBlindness.Protanomaly: |
||||
|
processor = new ProtanomalyProcessor(); |
||||
|
break; |
||||
|
|
||||
|
case ImageProcessorCore.ColorBlindness.Protanopia: |
||||
|
processor = new ProtanopiaProcessor(); |
||||
|
break; |
||||
|
|
||||
|
case ImageProcessorCore.ColorBlindness.Tritanomaly: |
||||
|
processor = new TritanomalyProcessor(); |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
processor = new TritanopiaProcessor(); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,65 +1,52 @@ |
|||||
// <copyright file="Contrast.cs" company="James Jackson-South">
|
// <copyright file="Contrast.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System; |
using Processors; |
||||
using System.Numerics; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// An <see cref="IImageProcessor"/> to change the contrast of an <see cref="Image"/>.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Contrast : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Contrast"/> class.
|
/// Alters the contrast component of the image.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="contrast">The new contrast of the image. Must be between -100 and 100.</param>
|
/// <param name="source">The image this method extends.</param>
|
||||
/// <exception cref="ArgumentException">
|
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
|
||||
/// <paramref name="contrast"/> is less than -100 or is greater than 100.
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
/// </exception>
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
public Contrast(int contrast) |
public static Image Contrast(this Image source, int amount, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
Guard.MustBeBetweenOrEqualTo(contrast, -100, 100, nameof(contrast)); |
return Contrast(source, amount, source.Bounds, progressHandler); |
||||
this.Value = contrast; |
|
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets the contrast value.
|
/// Alters the contrast component of the image.
|
||||
/// </summary>
|
/// </summary>
|
||||
public int Value { get; } |
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
|
||||
/// <inheritdoc/>
|
/// <param name="rectangle">
|
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Contrast(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
float contrast = (100f + this.Value) / 100f; |
ContrastProcessor processor = new ContrastProcessor(amount); |
||||
int sourceY = sourceRectangle.Y; |
processor.OnProgress += progressHandler; |
||||
int sourceBottom = sourceRectangle.Bottom; |
|
||||
int startX = sourceRectangle.X; |
try |
||||
int endX = sourceRectangle.Right; |
{ |
||||
Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1); |
return source.Process(rectangle, processor); |
||||
Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1); |
} |
||||
Parallel.For( |
finally |
||||
startY, |
{ |
||||
endY, |
processor.OnProgress -= progressHandler; |
||||
y => |
} |
||||
{ |
|
||||
if (y >= sourceY && y < sourceBottom) |
|
||||
{ |
|
||||
for (int x = startX; x < endX; x++) |
|
||||
{ |
|
||||
Vector4 color = Color.Expand(source[x, y]).ToVector4(); |
|
||||
color -= shiftVector; |
|
||||
color *= contrastVector; |
|
||||
color += shiftVector; |
|
||||
target[x, y] = Color.Compress(new Color(color)); |
|
||||
} |
|
||||
this.OnRowProcessed(); |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,63 @@ |
|||||
|
// <copyright file="DetectEdges.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Detects any edges within the image. Uses the <see cref="SobelProcessor"/> filter
|
||||
|
/// operating in greyscale mode.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image DetectEdges(this Image source, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return DetectEdges(source, source.Bounds, new SobelProcessor { Greyscale = true }, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Detects any edges within the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="filter">The filter for detecting edges.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image DetectEdges(this Image source, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return DetectEdges(source, source.Bounds, filter, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Detects any edges within the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="filter">The filter for detecting edges.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image DetectEdges(this Image source, Rectangle rectangle, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
filter.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, filter); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
filter.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
// <copyright file="Greyscale.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies greyscale toning to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="mode">The formula to apply to perform the operation.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Greyscale(source, source.Bounds, mode, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies greyscale toning to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="mode">The formula to apply to perform the operation.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
IImageProcessor processor = mode == GreyscaleMode.Bt709 |
||||
|
? (IImageProcessor)new GreyscaleBt709Processor() |
||||
|
: new GreyscaleBt601Processor(); |
||||
|
|
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
// <copyright file="GuassianBlur.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies a Guassian blur to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image GuassianBlur(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return GuassianBlur(source, sigma, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies a Guassian blur to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
GuassianBlurProcessor processor = new GuassianBlurProcessor(sigma); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
// <copyright file="GuassianSharpen.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies a Guassian sharpening filter to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image GuassianSharpen(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return GuassianSharpen(source, sigma, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies a Guassian sharpening filter to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
GuassianSharpenProcessor processor = new GuassianSharpenProcessor(sigma); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
// <copyright file="Hue.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Alters the hue component of the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="degrees">The angle in degrees to adjust the image.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Hue(this Image source, float degrees, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Hue(source, degrees, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Alters the hue component of the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="degrees">The angle in degrees to adjust the image.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Hue(this Image source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
HueProcessor processor = new HueProcessor(degrees); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,784 +0,0 @@ |
|||||
// <copyright file="ImageFilterExtensions.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Extensions methods for <see cref="Image"/> to apply filters to the image.
|
|
||||
/// </summary>
|
|
||||
public static class ImageFilterExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Alters the alpha component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Alpha(this Image source, int percent, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Alpha(source, percent, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the alpha component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Alpha(this Image source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Alpha processor = new Alpha(percent); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Combines the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color to set as the background.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image BackgroundColor(this Image source, Color color, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
BackgroundColor processor = new BackgroundColor(color); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(source.Bounds, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Combines the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">
|
|
||||
/// The image to blend with the currently processing image.
|
|
||||
/// Disposal of this image is the responsibility of the developer.
|
|
||||
/// </param>
|
|
||||
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Blend(this Image source, ImageBase image, int percent = 50, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Blend(source, image, percent, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Combines the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">
|
|
||||
/// The image to blend with the currently processing image.
|
|
||||
/// Disposal of this image is the responsibility of the developer.
|
|
||||
/// </param>
|
|
||||
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Blend(this Image source, ImageBase image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Blend processor = new Blend(image, percent); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies black and white toning to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image BlackWhite(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return BlackWhite(source, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies black and white toning to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image BlackWhite(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
BlackWhite processor = new BlackWhite(); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a box blur to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image BoxBlur(this Image source, int radius = 7, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return BoxBlur(source, radius, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a box blur to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image BoxBlur(this Image source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
BoxBlur processor = new BoxBlur(radius); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the brightness component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Brightness(this Image source, int amount, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Brightness(source, amount, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the brightness component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Brightness(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Brightness processor = new Brightness(amount); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies the given colorblindness simulator to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies the given colorblindness simulator to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
IImageProcessor processor; |
|
||||
|
|
||||
switch (colorBlindness) |
|
||||
{ |
|
||||
case Filters.ColorBlindness.Achromatomaly: |
|
||||
processor = new Achromatomaly(); |
|
||||
break; |
|
||||
|
|
||||
case Filters.ColorBlindness.Achromatopsia: |
|
||||
processor = new Achromatopsia(); |
|
||||
break; |
|
||||
|
|
||||
case Filters.ColorBlindness.Deuteranomaly: |
|
||||
processor = new Deuteranomaly(); |
|
||||
break; |
|
||||
|
|
||||
case Filters.ColorBlindness.Deuteranopia: |
|
||||
processor = new Deuteranopia(); |
|
||||
break; |
|
||||
|
|
||||
case Filters.ColorBlindness.Protanomaly: |
|
||||
processor = new Protanomaly(); |
|
||||
break; |
|
||||
|
|
||||
case Filters.ColorBlindness.Protanopia: |
|
||||
processor = new Protanopia(); |
|
||||
break; |
|
||||
|
|
||||
case Filters.ColorBlindness.Tritanomaly: |
|
||||
processor = new Tritanomaly(); |
|
||||
break; |
|
||||
|
|
||||
default: |
|
||||
processor = new Tritanopia(); |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the contrast component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Contrast(this Image source, int amount, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Contrast(source, amount, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the contrast component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Contrast(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Contrast processor = new Contrast(amount); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Detects any edges within the image. Uses the <see cref="Sobel"/> filter
|
|
||||
/// operating in greyscale mode.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image DetectEdges(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return DetectEdges(source, source.Bounds, new Sobel { Greyscale = true }, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Detects any edges within the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="filter">The filter for detecting edges.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image DetectEdges(this Image source, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return DetectEdges(source, source.Bounds, filter, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Detects any edges within the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="filter">The filter for detecting edges.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image DetectEdges(this Image source, Rectangle rectangle, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
filter.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, filter); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
filter.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies greyscale toning to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="mode">The formula to apply to perform the operation.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Greyscale(source, source.Bounds, mode, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies greyscale toning to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="mode">The formula to apply to perform the operation.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
IImageProcessor processor = mode == GreyscaleMode.Bt709 |
|
||||
? (IImageProcessor)new GreyscaleBt709() |
|
||||
: new GreyscaleBt601(); |
|
||||
|
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a Guassian blur to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image GuassianBlur(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return GuassianBlur(source, sigma, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a Guassian blur to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
GuassianBlur processor = new GuassianBlur(sigma); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a Guassian sharpening filter to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image GuassianSharpen(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return GuassianSharpen(source, sigma, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a Guassian sharpening filter to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
GuassianSharpen processor = new GuassianSharpen(sigma); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the hue component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="degrees">The angle in degrees to adjust the image.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Hue(this Image source, float degrees, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Hue(source, degrees, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the hue component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="degrees">The angle in degrees to adjust the image.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Hue(this Image source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Hue processor = new Hue(degrees); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Inverts the colors of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Invert(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Invert(source, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Inverts the colors of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Invert(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Invert processor = new Invert(); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the colors of the image recreating an old Kodachrome camera effect.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Kodachrome(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Kodachrome(source, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the colors of the image recreating an old Kodachrome camera effect.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Kodachrome(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Kodachrome processor = new Kodachrome(); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the colors of the image recreating an old Lomograph camera effect.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Lomograph(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Lomograph(source, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the colors of the image recreating an old Lomograph camera effect.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Lomograph(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Lomograph processor = new Lomograph(); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the colors of the image recreating an old Polaroid camera effect.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Polaroid(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Polaroid(source, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the colors of the image recreating an old Polaroid camera effect.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Polaroid(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Polaroid processor = new Polaroid(); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Pixelates and image with the given pixel size.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="size">The size of the pixels.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Pixelate(this Image source, int size = 4, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Pixelate(source, size, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Pixelates and image with the given pixel size.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="size">The size of the pixels.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Pixelate(this Image source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Pixelate processor = new Pixelate(size); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the saturation component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Saturation(this Image source, int amount, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Saturation(source, amount, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Alters the saturation component of the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Saturation(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Saturation processor = new Saturation(amount); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies sepia toning to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Sepia(this Image source, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
return Sepia(source, source.Bounds, progressHandler); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies sepia toning to the image.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="rectangle">
|
|
||||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|
||||
/// </param>
|
|
||||
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
|
||||
/// <returns>The <see cref="Image"/>.</returns>
|
|
||||
public static Image Sepia(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
|
||||
{ |
|
||||
Sepia processor = new Sepia(); |
|
||||
processor.OnProgress += progressHandler; |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
return source.Process(rectangle, processor); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
processor.OnProgress -= progressHandler; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,43 +1,50 @@ |
|||||
// <copyright file="Invert.cs" company="James Jackson-South">
|
// <copyright file="Invert.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System.Numerics; |
using Processors; |
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// An <see cref="IImageProcessor"/> to invert the colors of an <see cref="Image"/>.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Invert : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <summary>
|
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
/// Inverts the colors of the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Invert(this Image source, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
int sourceY = sourceRectangle.Y; |
return Invert(source, source.Bounds, progressHandler); |
||||
int sourceBottom = sourceRectangle.Bottom; |
} |
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
/// <summary>
|
||||
Vector3 inverseVector = Vector3.One; |
/// Inverts the colors of the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Invert(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
InvertProcessor processor = new InvertProcessor(); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
Parallel.For( |
try |
||||
startY, |
{ |
||||
endY, |
return source.Process(rectangle, processor); |
||||
y => |
} |
||||
{ |
finally |
||||
if (y >= sourceY && y < sourceBottom) |
{ |
||||
{ |
processor.OnProgress -= progressHandler; |
||||
for (int x = startX; x < endX; x++) |
} |
||||
{ |
|
||||
Color color = source[x, y]; |
|
||||
Vector3 vector = inverseVector - color.ToVector3(); |
|
||||
target[x, y] = new Color(vector, color.A); |
|
||||
} |
|
||||
this.OnRowProcessed(); |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,50 @@ |
|||||
|
// <copyright file="Kodachrome.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Alters the colors of the image recreating an old Kodachrome camera effect.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Kodachrome(this Image source, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Kodachrome(source, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Alters the colors of the image recreating an old Kodachrome camera effect.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Kodachrome(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
KodachromeProcessor processor = new KodachromeProcessor(); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
// <copyright file="Lomograph.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Alters the colors of the image recreating an old Lomograph camera effect.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Lomograph(this Image source, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Lomograph(source, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Alters the colors of the image recreating an old Lomograph camera effect.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Lomograph(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
LomographProcessor processor = new LomographProcessor(); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,93 +1,52 @@ |
|||||
// <copyright file="Invert.cs" company="James Jackson-South">
|
// <copyright file="Pixelate.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore |
||||
{ |
{ |
||||
using System; |
using Processors; |
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// An <see cref="IImageProcessor"/> to invert the colors of an <see cref="Image"/>.
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Pixelate : ParallelImageProcessor |
public static partial class ImageExtensions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Pixelate"/> class.
|
/// Pixelates and image with the given pixel size.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="size">The size of the pixels. Must be greater than 0.</param>
|
/// <param name="source">The image this method extends.</param>
|
||||
/// <exception cref="ArgumentException">
|
/// <param name="size">The size of the pixels.</param>
|
||||
/// <paramref name="size"/> is less than 0 or equal to 0.
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
/// </exception>
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
public Pixelate(int size) |
public static Image Pixelate(this Image source, int size = 4, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
Guard.MustBeGreaterThan(size, 0, nameof(size)); |
return Pixelate(source, size, source.Bounds, progressHandler); |
||||
this.Value = size; |
|
||||
} |
} |
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override int Parallelism { get; set; } = 1; |
|
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Gets or the pixel size.
|
/// Pixelates and image with the given pixel size.
|
||||
/// </summary>
|
/// </summary>
|
||||
public int Value { get; } |
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="size">The size of the pixels.</param>
|
||||
/// <inheritdoc/>
|
/// <param name="rectangle">
|
||||
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Pixelate(this Image source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
{ |
{ |
||||
int sourceY = sourceRectangle.Y; |
PixelateProcessor processor = new PixelateProcessor(size); |
||||
int sourceBottom = sourceRectangle.Bottom; |
processor.OnProgress += progressHandler; |
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
try |
||||
int size = this.Value; |
{ |
||||
int offset = this.Value / 2; |
return source.Process(rectangle, processor); |
||||
|
} |
||||
// Get the range on the y-plane to choose from.
|
finally |
||||
IEnumerable<int> range = EnumerableExtensions.SteppedRange(startY, i => i < endY, size); |
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
Parallel.ForEach( |
} |
||||
range, |
|
||||
y => |
|
||||
{ |
|
||||
if (y >= sourceY && y < sourceBottom) |
|
||||
{ |
|
||||
for (int x = startX; x < endX; x += size) |
|
||||
{ |
|
||||
|
|
||||
int offsetX = offset; |
|
||||
int offsetY = offset; |
|
||||
|
|
||||
// Make sure that the offset is within the boundary of the
|
|
||||
// image.
|
|
||||
while (y + offsetY >= sourceBottom) |
|
||||
{ |
|
||||
offsetY--; |
|
||||
} |
|
||||
|
|
||||
while (x + offsetX >= endX) |
|
||||
{ |
|
||||
offsetX--; |
|
||||
} |
|
||||
|
|
||||
// Get the pixel color in the centre of the soon to be pixelated area.
|
|
||||
// ReSharper disable AccessToDisposedClosure
|
|
||||
Color pixel = source[x + offsetX, y + offsetY]; |
|
||||
|
|
||||
// For each pixel in the pixelate size, set it to the centre color.
|
|
||||
for (int l = y; l < y + size && l < sourceBottom; l++) |
|
||||
{ |
|
||||
for (int k = x; k < x + size && k < endX; k++) |
|
||||
{ |
|
||||
target[k, l] = pixel; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
this.OnRowProcessed(); |
|
||||
} |
|
||||
}); |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,50 @@ |
|||||
|
// <copyright file="Polaroid.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Alters the colors of the image recreating an old Polaroid camera effect.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Polaroid(this Image source, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Polaroid(source, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Alters the colors of the image recreating an old Polaroid camera effect.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Polaroid(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
PolaroidProcessor processor = new PolaroidProcessor(); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
// <copyright file="AlphaProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// An <see cref="IImageProcessor"/> to change the Alpha of an <see cref="Image"/>.
|
||||
|
/// </summary>
|
||||
|
public class AlphaProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="AlphaProcessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="percent">The percentage to adjust the opacity of the image. Must be between 0 and 100.</param>
|
||||
|
/// <exception cref="ArgumentException">
|
||||
|
/// <paramref name="percent"/> is less than 0 or is greater than 100.
|
||||
|
/// </exception>
|
||||
|
public AlphaProcessor(int percent) |
||||
|
{ |
||||
|
Guard.MustBeBetweenOrEqualTo(percent, 0, 100, nameof(percent)); |
||||
|
this.Value = percent; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the alpha value.
|
||||
|
/// </summary>
|
||||
|
public int Value { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
float alpha = this.Value / 100f; |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
Vector4 alphaVector = new Vector4(1, 1, 1, alpha); |
||||
|
|
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Vector4 color = Color.ToNonPremultiplied(sourcePixels[x, y]).ToVector4(); |
||||
|
color *= alphaVector; |
||||
|
targetPixels[x, y] = Color.FromNonPremultiplied(new Color(color)); |
||||
|
} |
||||
|
|
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
// <copyright file="BackgroundColorProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the background color of the image.
|
||||
|
/// </summary>
|
||||
|
public class BackgroundColorProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The epsilon for comparing floating point numbers.
|
||||
|
/// </summary>
|
||||
|
private const float Epsilon = 0.001f; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="BackgroundColorProcessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The <see cref="Color"/> to set the background color to.</param>
|
||||
|
public BackgroundColorProcessor(Color color) |
||||
|
{ |
||||
|
this.Value = Color.FromNonPremultiplied(color); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the background color value.
|
||||
|
/// </summary>
|
||||
|
public Color Value { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
Color backgroundColor = this.Value; |
||||
|
|
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Color color = sourcePixels[x, y]; |
||||
|
float a = color.A; |
||||
|
|
||||
|
if (a < 1 && a > 0) |
||||
|
{ |
||||
|
color = Color.Lerp(color, backgroundColor, .5f); |
||||
|
} |
||||
|
|
||||
|
if (Math.Abs(a) < Epsilon) |
||||
|
{ |
||||
|
color = backgroundColor; |
||||
|
} |
||||
|
|
||||
|
targetPixels[x, y] = color; |
||||
|
} |
||||
|
|
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
// <copyright file="BlendProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Combines two images together by blending the pixels.
|
||||
|
/// </summary>
|
||||
|
public class BlendProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The image to blend.
|
||||
|
/// </summary>
|
||||
|
private readonly ImageBase blend; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="BlendProcessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">
|
||||
|
/// The image to blend with the currently processing image.
|
||||
|
/// Disposal of this image is the responsibility of the developer.
|
||||
|
/// </param>
|
||||
|
/// <param name="alpha">The opacity of the image to blend. Between 0 and 100.</param>
|
||||
|
public BlendProcessor(ImageBase image, int alpha = 100) |
||||
|
{ |
||||
|
Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha)); |
||||
|
this.blend = image; |
||||
|
this.Value = alpha; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the alpha percentage value.
|
||||
|
/// </summary>
|
||||
|
public int Value { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
Rectangle bounds = this.blend.Bounds; |
||||
|
float alpha = this.Value / 100f; |
||||
|
|
||||
|
using (PixelAccessor toBlendPixels = this.blend.Lock()) |
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Color color = sourcePixels[x, y]; |
||||
|
|
||||
|
if (bounds.Contains(x, y)) |
||||
|
{ |
||||
|
Color blendedColor = toBlendPixels[x, y]; |
||||
|
|
||||
|
if (blendedColor.A > 0) |
||||
|
{ |
||||
|
// Lerping colors is dependent on the alpha of the blended color
|
||||
|
float alphaFactor = alpha > 0 ? alpha : blendedColor.A; |
||||
|
color = Color.Lerp(color, blendedColor, alphaFactor); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
targetPixels[x, y] = color; |
||||
|
} |
||||
|
|
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
// <copyright file="BrightnessProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// An <see cref="IImageProcessor"/> to change the brightness of an <see cref="Image"/>.
|
||||
|
/// </summary>
|
||||
|
public class BrightnessProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="BrightnessProcessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="brightness">The new brightness of the image. Must be between -100 and 100.</param>
|
||||
|
/// <exception cref="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 Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
float brightness = this.Value / 100f; |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
|
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Color color = Color.Expand(sourcePixels[x, y]); |
||||
|
|
||||
|
Vector3 vector3 = color.ToVector3(); |
||||
|
vector3 += new Vector3(brightness); |
||||
|
|
||||
|
targetPixels[x, y] = Color.Compress(new Color(vector3, color.A)); |
||||
|
} |
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="BlackWhite.cs" company="James Jackson-South">
|
// <copyright file="BlackWhiteProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image to their black and white equivalent.
|
/// Converts the colors of the image to their black and white equivalent.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class BlackWhite : ColorMatrixFilter |
public class BlackWhiteProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Achromatomaly.cs" company="James Jackson-South">
|
// <copyright file="AchromatomalyProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
|
/// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Achromatomaly : ColorMatrixFilter |
public class AchromatomalyProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Achromatopsia.cs" company="James Jackson-South">
|
// <copyright file="AchromatopsiaProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
|
/// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Achromatopsia : ColorMatrixFilter |
public class AchromatopsiaProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Deuteranomaly.cs" company="James Jackson-South">
|
// <copyright file="DeuteranomalyProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness.
|
/// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Deuteranomaly : ColorMatrixFilter |
public class DeuteranomalyProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Deuteranopia.cs" company="James Jackson-South">
|
// <copyright file="DeuteranopiaProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness.
|
/// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Deuteranopia : ColorMatrixFilter |
public class DeuteranopiaProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Protanomaly.cs" company="James Jackson-South">
|
// <copyright file="ProtanomalyProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness.
|
/// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Protanomaly : ColorMatrixFilter |
public class ProtanomalyProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Protanopia.cs" company="James Jackson-South">
|
// <copyright file="ProtanopiaProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness.
|
/// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Protanopia : ColorMatrixFilter |
public class ProtanopiaProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Tritanomaly.cs" company="James Jackson-South">
|
// <copyright file="TritanomalyProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness.
|
/// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Tritanomaly : ColorMatrixFilter |
public class TritanomalyProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Tritanopia.cs" company="James Jackson-South">
|
// <copyright file="TritanopiaProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness.
|
/// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Tritanopia : ColorMatrixFilter |
public class TritanopiaProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -1,16 +1,16 @@ |
|||||
// <copyright file="Kodachrome.cs" company="James Jackson-South">
|
// <copyright file="KodachromeProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
using System.Numerics; |
using System.Numerics; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Converts the colors of the image recreating an old Kodachrome camera effect.
|
/// Converts the colors of the image recreating an old Kodachrome camera effect.
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Kodachrome : ColorMatrixFilter |
public class KodachromeProcessor : ColorMatrixFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override Matrix4x4 Matrix => new Matrix4x4() |
public override Matrix4x4 Matrix => new Matrix4x4() |
||||
@ -0,0 +1,70 @@ |
|||||
|
// <copyright file="ContrastProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// An <see cref="IImageProcessor"/> to change the contrast of an <see cref="Image"/>.
|
||||
|
/// </summary>
|
||||
|
public class ContrastProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ContrastProcessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="contrast">The new contrast of the image. Must be between -100 and 100.</param>
|
||||
|
/// <exception cref="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 Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
float contrast = (100f + this.Value) / 100f; |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1); |
||||
|
Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1); |
||||
|
|
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Vector4 color = Color.Expand(sourcePixels[x, y]).ToVector4(); |
||||
|
color -= shiftVector; |
||||
|
color *= contrastVector; |
||||
|
color += shiftVector; |
||||
|
targetPixels[x, y] = Color.Compress(new Color(color)); |
||||
|
} |
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Kayyali.cs" company="James Jackson-South">
|
// <copyright file="KayyaliProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Kayyali operator filter.
|
/// The Kayyali operator filter.
|
||||
/// <see href="http://edgedetection.webs.com/"/>
|
/// <see href="http://edgedetection.webs.com/"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Kayyali : EdgeDetector2DFilter |
public class KayyaliProcessor : EdgeDetector2DFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelX => new float[,] |
public override float[,] KernelX => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Kirsch.cs" company="James Jackson-South">
|
// <copyright file="KirschProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Kirsch operator filter.
|
/// The Kirsch operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Kirsch_operator"/>
|
/// <see href="http://en.wikipedia.org/wiki/Kirsch_operator"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Kirsch : EdgeDetector2DFilter |
public class KirschProcessor : EdgeDetector2DFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelX => new float[,] |
public override float[,] KernelX => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Laplacian3X3.cs" company="James Jackson-South">
|
// <copyright file="Laplacian3X3Processor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Laplacian 3 x 3 operator filter.
|
/// The Laplacian 3 x 3 operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
|
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Laplacian3X3 : EdgeDetectorFilter |
public class Laplacian3X3Processor : EdgeDetectorFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelXY => new float[,] |
public override float[,] KernelXY => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Laplacian5X5.cs" company="James Jackson-South">
|
// <copyright file="Laplacian5X5Processor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Laplacian 5 x 5 operator filter.
|
/// The Laplacian 5 x 5 operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
|
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Laplacian5X5 : EdgeDetectorFilter |
public class Laplacian5X5Processor : EdgeDetectorFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelXY => new float[,] |
public override float[,] KernelXY => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="LaplacianOfGaussian.cs" company="James Jackson-South">
|
// <copyright file="LaplacianOfGaussianProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Laplacian of Gaussian operator filter.
|
/// The Laplacian of Gaussian operator filter.
|
||||
/// <see href="http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html"/>
|
/// <see href="http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class LaplacianOfGaussian : EdgeDetectorFilter |
public class LaplacianOfGaussianProcessor : EdgeDetectorFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelXY => new float[,] |
public override float[,] KernelXY => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Prewitt.cs" company="James Jackson-South">
|
// <copyright file="PrewittProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Prewitt operator filter.
|
/// The Prewitt operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/>
|
/// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Prewitt : EdgeDetector2DFilter |
public class PrewittProcessor : EdgeDetector2DFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelX => new float[,] |
public override float[,] KernelX => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="RobertsCross.cs" company="James Jackson-South">
|
// <copyright file="RobertsCrossProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Roberts Cross operator filter.
|
/// The Roberts Cross operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/>
|
/// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class RobertsCross : EdgeDetector2DFilter |
public class RobertsCrossProcessor : EdgeDetector2DFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelX => new float[,] |
public override float[,] KernelX => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Scharr.cs" company="James Jackson-South">
|
// <copyright file="ScharrProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Scharr operator filter.
|
/// The Scharr operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators"/>
|
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Scharr : EdgeDetector2DFilter |
public class ScharrProcessor : EdgeDetector2DFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelX => new float[,] |
public override float[,] KernelX => new float[,] |
||||
@ -1,15 +1,15 @@ |
|||||
// <copyright file="Sobel.cs" company="James Jackson-South">
|
// <copyright file="SobelProcessor.cs" company="James Jackson-South">
|
||||
// Copyright (c) James Jackson-South and contributors.
|
// Copyright (c) James Jackson-South and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
// </copyright>
|
// </copyright>
|
||||
|
|
||||
namespace ImageProcessorCore.Filters |
namespace ImageProcessorCore.Processors |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// The Sobel operator filter.
|
/// The Sobel operator filter.
|
||||
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator"/>
|
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator"/>
|
||||
/// </summary>
|
/// </summary>
|
||||
public class Sobel : EdgeDetector2DFilter |
public class SobelProcessor : EdgeDetector2DFilter |
||||
{ |
{ |
||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||
public override float[,] KernelX => new float[,] |
public override float[,] KernelX => new float[,] |
||||
@ -0,0 +1,48 @@ |
|||||
|
// <copyright file="InvertProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System.Numerics; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// An <see cref="IImageProcessor"/> to invert the colors of an <see cref="Image"/>.
|
||||
|
/// </summary>
|
||||
|
public class InvertProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <inheritdoc/>
|
||||
|
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
Vector3 inverseVector = Vector3.One; |
||||
|
|
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Color color = sourcePixels[x, y]; |
||||
|
Vector3 vector = inverseVector - color.ToVector3(); |
||||
|
targetPixels[x, y] = new Color(vector, color.A); |
||||
|
} |
||||
|
|
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
// <copyright file="PixelateProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// An <see cref="IImageProcessor"/> to invert the colors of an <see cref="Image"/>.
|
||||
|
/// </summary>
|
||||
|
public class PixelateProcessor : ParallelImageProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelateProcessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="size">The size of the pixels. Must be greater than 0.</param>
|
||||
|
/// <exception cref="ArgumentException">
|
||||
|
/// <paramref name="size"/> is less than 0 or equal to 0.
|
||||
|
/// </exception>
|
||||
|
public PixelateProcessor(int size) |
||||
|
{ |
||||
|
Guard.MustBeGreaterThan(size, 0, nameof(size)); |
||||
|
this.Value = size; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int Parallelism { get; set; } = 1; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or the pixel size.
|
||||
|
/// </summary>
|
||||
|
public int Value { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
int size = this.Value; |
||||
|
int offset = this.Value / 2; |
||||
|
|
||||
|
// Get the range on the y-plane to choose from.
|
||||
|
IEnumerable<int> range = EnumerableExtensions.SteppedRange(startY, i => i < endY, size); |
||||
|
|
||||
|
using (PixelAccessor sourcePixels = source.Lock()) |
||||
|
using (PixelAccessor targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.ForEach( |
||||
|
range, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x += size) |
||||
|
{ |
||||
|
|
||||
|
int offsetX = offset; |
||||
|
int offsetY = offset; |
||||
|
|
||||
|
// Make sure that the offset is within the boundary of the
|
||||
|
// image.
|
||||
|
while (y + offsetY >= sourceBottom) |
||||
|
{ |
||||
|
offsetY--; |
||||
|
} |
||||
|
|
||||
|
while (x + offsetX >= endX) |
||||
|
{ |
||||
|
offsetX--; |
||||
|
} |
||||
|
|
||||
|
// Get the pixel color in the centre of the soon to be pixelated area.
|
||||
|
// ReSharper disable AccessToDisposedClosure
|
||||
|
Color pixel = sourcePixels[x + offsetX, y + offsetY]; |
||||
|
|
||||
|
// For each pixel in the pixelate size, set it to the centre color.
|
||||
|
for (int l = y; l < y + size && l < sourceBottom; l++) |
||||
|
{ |
||||
|
for (int k = x; k < x + size && k < endX; k++) |
||||
|
{ |
||||
|
targetPixels[k, l] = pixel; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
// <copyright file="Saturation.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Alters the saturation component of the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Saturation(this Image source, int amount, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Saturation(source, amount, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Alters the saturation component of the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Saturation(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
SaturationProcessor processor = new SaturationProcessor(amount); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
// <copyright file="Sepia.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>-------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies sepia toning to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Sepia(this Image source, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
return Sepia(source, source.Bounds, progressHandler); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies sepia toning to the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="rectangle">
|
||||
|
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
||||
|
/// </param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image"/>.</returns>
|
||||
|
public static Image Sepia(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null) |
||||
|
{ |
||||
|
SepiaProcessor processor = new SepiaProcessor(); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(rectangle, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,103 +0,0 @@ |
|||||
// <copyright file="IImage.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageProcessorCore |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.IO; |
|
||||
|
|
||||
using ImageProcessorCore.Formats; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
|
|
||||
/// </summary>
|
|
||||
public interface IImage : IImageBase |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets or sets the resolution of the image in x- direction. It is defined as
|
|
||||
/// number of dots per inch and should be an positive value.
|
|
||||
/// </summary>
|
|
||||
/// <value>The density of the image in x- direction.</value>
|
|
||||
double HorizontalResolution { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the resolution of the image in y- direction. It is defined as
|
|
||||
/// number of dots per inch and should be an positive value.
|
|
||||
/// </summary>
|
|
||||
/// <value>The density of the image in y- direction.</value>
|
|
||||
double VerticalResolution { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the width of the image in inches. It is calculated as the width of the image
|
|
||||
/// in pixels multiplied with the density. When the density is equals or less than zero
|
|
||||
/// the default value is used.
|
|
||||
/// </summary>
|
|
||||
/// <value>The width of the image in inches.</value>
|
|
||||
double InchWidth { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the height of the image in inches. It is calculated as the height of the image
|
|
||||
/// in pixels multiplied with the density. When the density is equals or less than zero
|
|
||||
/// the default value is used.
|
|
||||
/// </summary>
|
|
||||
/// <value>The height of the image in inches.</value>
|
|
||||
double InchHeight { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets a value indicating whether this image is animated.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// <c>True</c> if this image is animated; otherwise, <c>false</c>.
|
|
||||
/// </value>
|
|
||||
bool IsAnimated { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the number of times any animation is repeated.
|
|
||||
/// <remarks>0 means to repeat indefinitely.</remarks>
|
|
||||
/// </summary>
|
|
||||
ushort RepeatCount { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the currently loaded image format.
|
|
||||
/// </summary>
|
|
||||
IImageFormat CurrentImageFormat { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the other frames for the animation.
|
|
||||
/// </summary>
|
|
||||
/// <value>The list of frame images.</value>
|
|
||||
IList<ImageFrame> Frames { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the list of properties for storing meta information about this image.
|
|
||||
/// </summary>
|
|
||||
/// <value>A list of image properties.</value>
|
|
||||
IList<ImageProperty> Properties { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Saves the image to the given stream using the currently loaded image format.
|
|
||||
/// </summary>
|
|
||||
/// <param name="stream">The stream to save the image to.</param>
|
|
||||
/// <exception cref="ArgumentNullException">Thrown if the stream is null.</exception>
|
|
||||
void Save(Stream stream); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Saves the image to the given stream using the given image format.
|
|
||||
/// </summary>
|
|
||||
/// <param name="stream">The stream to save the image to.</param>
|
|
||||
/// <param name="format">The format to save the image as.</param>
|
|
||||
/// <exception cref="ArgumentNullException">Thrown if the stream is null.</exception>
|
|
||||
void Save(Stream stream, IImageFormat format); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Saves the image to the given stream using the given image encoder.
|
|
||||
/// </summary>
|
|
||||
/// <param name="stream">The stream to save the image to.</param>
|
|
||||
/// <param name="encoder">The encoder to save the image with.</param>
|
|
||||
/// <exception cref="ArgumentNullException">Thrown if the stream is null.</exception>
|
|
||||
void Save(Stream stream, IImageEncoder encoder); |
|
||||
} |
|
||||
} |
|
||||
@ -1,106 +0,0 @@ |
|||||
// <copyright file="IImageBase.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageProcessorCore |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Runtime.CompilerServices; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Encapsulates the basic properties and methods required to manipulate images.
|
|
||||
/// </summary>
|
|
||||
public interface IImageBase |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the image pixels as byte array.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// The returned array has a length of Width * Height * 4 bytes
|
|
||||
/// and stores the red, the green, the blue, and the alpha value for
|
|
||||
/// each pixel in this order.
|
|
||||
/// </remarks>
|
|
||||
float[] Pixels { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the width in pixels.
|
|
||||
/// </summary>
|
|
||||
int Width { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the height in pixels.
|
|
||||
/// </summary>
|
|
||||
int Height { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the pixel ratio made up of the width and height.
|
|
||||
/// </summary>
|
|
||||
double PixelRatio { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the <see cref="Rectangle"/> representing the bounds of the image.
|
|
||||
/// </summary>
|
|
||||
Rectangle Bounds { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets th quality of the image. This affects the output quality of lossy image formats.
|
|
||||
/// </summary>
|
|
||||
int Quality { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the frame delay for animated images.
|
|
||||
/// If not 0, this field specifies the number of hundredths (1/100) of a second to
|
|
||||
/// wait before continuing with the processing of the Data Stream.
|
|
||||
/// The clock starts ticking immediately after the graphic is rendered.
|
|
||||
/// </summary>
|
|
||||
int FrameDelay { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets the color of a pixel at the specified position.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">
|
|
||||
/// The x-coordinate of the pixel. Must be greater
|
|
||||
/// than zero and smaller than the width of the pixel.
|
|
||||
/// </param>
|
|
||||
/// <param name="y">
|
|
||||
/// The y-coordinate of the pixel. Must be greater
|
|
||||
/// than zero and smaller than the width of the pixel.
|
|
||||
/// </param>
|
|
||||
/// <returns>The <see cref="Color"/> at the specified position.</returns>
|
|
||||
Color this[int x, int y] { get; set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Sets the pixel array of the image to the given value.
|
|
||||
/// </summary>
|
|
||||
/// <param name="width">The new width of the image. Must be greater than zero.</param>
|
|
||||
/// <param name="height">The new height of the image. Must be greater than zero.</param>
|
|
||||
/// <param name="pixels">
|
|
||||
/// The array with colors. Must be a multiple of four times the width and height.
|
|
||||
/// </param>
|
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
|
||||
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
|
|
||||
/// </exception>
|
|
||||
/// <exception cref="ArgumentException">
|
|
||||
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height * 4.
|
|
||||
/// </exception>
|
|
||||
void SetPixels(int width, int height, float[] pixels); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Sets the pixel array of the image to the given value, creating a copy of
|
|
||||
/// the original pixels.
|
|
||||
/// </summary>
|
|
||||
/// <param name="width">The new width of the image. Must be greater than zero.</param>
|
|
||||
/// <param name="height">The new height of the image. Must be greater than zero.</param>
|
|
||||
/// <param name="pixels">
|
|
||||
/// The array with colors. Must be a multiple of four times the width and height.
|
|
||||
/// </param>
|
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
|
||||
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
|
|
||||
/// </exception>
|
|
||||
/// <exception cref="ArgumentException">
|
|
||||
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height * 4.
|
|
||||
/// </exception>
|
|
||||
void ClonePixels(int width, int height, float[] pixels); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,164 @@ |
|||||
|
// <copyright file="PixelAccessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides per-pixel access to an images pixels.
|
||||
|
/// </summary>
|
||||
|
public sealed unsafe class PixelAccessor : IDisposable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The position of the first pixel in the bitmap.
|
||||
|
/// </summary>
|
||||
|
private float* pixelsBase; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides a way to access the pixels from unmanaged memory.
|
||||
|
/// </summary>
|
||||
|
private GCHandle pixelsHandle; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A value indicating whether this instance of the given entity has been disposed.
|
||||
|
/// </summary>
|
||||
|
/// <value><see langword="true"/> if this instance has been disposed; otherwise, <see langword="false"/>.</value>
|
||||
|
/// <remarks>
|
||||
|
/// If the entity is disposed, it must not be disposed a second
|
||||
|
/// time. The isDisposed field is set the first time the entity
|
||||
|
/// is disposed. If the isDisposed field is true, then the Dispose()
|
||||
|
/// method will not dispose again. This help not to prolong the entity's
|
||||
|
/// life in the Garbage Collector.
|
||||
|
/// </remarks>
|
||||
|
private bool isDisposed; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="PixelAccessor"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">
|
||||
|
/// The image to provide pixel access for.
|
||||
|
/// </param>
|
||||
|
public PixelAccessor(ImageBase image) |
||||
|
{ |
||||
|
Guard.NotNull(image, nameof(image)); |
||||
|
Guard.MustBeGreaterThan(image.Width, 0, "image width"); |
||||
|
Guard.MustBeGreaterThan(image.Height, 0, "image height"); |
||||
|
|
||||
|
int size = image.Pixels.Length; |
||||
|
this.Width = image.Width; |
||||
|
this.Height = image.Height; |
||||
|
|
||||
|
// Assign the pointer.
|
||||
|
// If buffer is allocated on Large Object Heap i.e > 85Kb, then we are going to pin it instead of making a copy.
|
||||
|
if (size > 87040) |
||||
|
{ |
||||
|
this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned); |
||||
|
this.pixelsBase = (float*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
fixed (float* pbuffer = image.Pixels) |
||||
|
{ |
||||
|
this.pixelsBase = pbuffer; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Finalizes an instance of the <see cref="PixelAccessor"/> class.
|
||||
|
/// </summary>
|
||||
|
~PixelAccessor() |
||||
|
{ |
||||
|
this.Dispose(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the width of the image.
|
||||
|
/// </summary>
|
||||
|
public int Width { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the height of the image.
|
||||
|
/// </summary>
|
||||
|
public int Height { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the color of a pixel at the specified position.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">
|
||||
|
/// The x-coordinate of the pixel. Must be greater
|
||||
|
/// than zero and smaller than the width of the pixel.
|
||||
|
/// </param>
|
||||
|
/// <param name="y">
|
||||
|
/// The y-coordinate of the pixel. Must be greater
|
||||
|
/// than zero and smaller than the width of the pixel.
|
||||
|
/// </param>
|
||||
|
/// <returns>The <see cref="Color"/> at the specified position.</returns>
|
||||
|
public Color this[int x, int y] |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
#if DEBUG
|
||||
|
if ((x < 0) || (x >= this.Width)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); |
||||
|
} |
||||
|
|
||||
|
if ((y < 0) || (y >= this.Height)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); |
||||
|
} |
||||
|
#endif
|
||||
|
return *((Color*)(this.pixelsBase + ((y * this.Width) + x) * 4)); |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
#if DEBUG
|
||||
|
if ((x < 0) || (x >= this.Width)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); |
||||
|
} |
||||
|
|
||||
|
if ((y < 0) || (y >= this.Height)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); |
||||
|
} |
||||
|
#endif
|
||||
|
*(Color*)(this.pixelsBase + (((y * this.Width) + x) * 4)) = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
|
/// </summary>
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (this.isDisposed) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.pixelsHandle.IsAllocated) |
||||
|
{ |
||||
|
this.pixelsHandle.Free(); |
||||
|
} |
||||
|
|
||||
|
this.pixelsBase = null; |
||||
|
|
||||
|
// Note disposing is done.
|
||||
|
this.isDisposed = true; |
||||
|
|
||||
|
// This object will be cleaned up by the Dispose method.
|
||||
|
// Therefore, you should call GC.SuppressFinalize to
|
||||
|
// take this object off the finalization queue
|
||||
|
// and prevent finalization code for this object
|
||||
|
// from executing a second time.
|
||||
|
GC.SuppressFinalize(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue