mirror of https://github.com/SixLabors/ImageSharp
42 changed files with 465 additions and 401 deletions
@ -0,0 +1,69 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="PolaroidMatrixFilter.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// Encapsulates methods with which to add a Polaroid filter to an image.
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Filters.Photo |
|||
{ |
|||
using System.Drawing; |
|||
using System.Drawing.Imaging; |
|||
|
|||
using ImageProcessor.Imaging.Helpers; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates methods with which to add a Polaroid filter to an image.
|
|||
/// </summary>
|
|||
internal class PolaroidMatrixFilter : MatrixFilterBase |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for this filter instance.
|
|||
/// </summary>
|
|||
public override ColorMatrix Matrix |
|||
{ |
|||
get { return ColorMatrixes.Polaroid; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Processes the image.
|
|||
/// </summary>
|
|||
/// <param name="image">The current image to process</param>
|
|||
/// <param name="newImage">The new Image to return</param>
|
|||
/// <returns>
|
|||
/// The processed image.
|
|||
/// </returns>
|
|||
public override Image TransformImage(Image image, Image newImage) |
|||
{ |
|||
using (Graphics graphics = Graphics.FromImage(newImage)) |
|||
{ |
|||
using (ImageAttributes attributes = new ImageAttributes()) |
|||
{ |
|||
attributes.SetColorMatrix(this.Matrix); |
|||
|
|||
Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height); |
|||
|
|||
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); |
|||
} |
|||
} |
|||
|
|||
// Fade the contrast
|
|||
newImage = Adjustments.Contrast((Bitmap)newImage, -30); |
|||
|
|||
// Add a glow to the image.
|
|||
newImage = Effects.Glow((Bitmap)newImage, Color.FromArgb(70, 255, 153, 102)); |
|||
|
|||
// Add a vignette to finish the effect.
|
|||
newImage = Effects.Vignette((Bitmap)newImage, Color.FromArgb(80, 0, 0)); |
|||
|
|||
// Reassign the image.
|
|||
image.Dispose(); |
|||
image = newImage; |
|||
|
|||
return image; |
|||
} |
|||
} |
|||
} |
|||
@ -1,99 +0,0 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="PolaroidMatrixFilter.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// Encapsulates methods with which to add a Polaroid filter to an image.
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Filters |
|||
{ |
|||
#region Using
|
|||
using System.Drawing; |
|||
using System.Drawing.Drawing2D; |
|||
using System.Drawing.Imaging; |
|||
using ImageProcessor.Processors; |
|||
#endregion
|
|||
|
|||
/// <summary>
|
|||
/// Encapsulates methods with which to add a Polaroid filter to an image.
|
|||
/// </summary>
|
|||
internal class PolaroidMatrixFilter : MatrixFilterBase |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for this filter instance.
|
|||
/// </summary>
|
|||
public override ColorMatrix Matrix |
|||
{ |
|||
get { return ColorMatrixes.Polaroid; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Processes the image.
|
|||
/// </summary>
|
|||
/// <param name="factory">
|
|||
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
|
|||
/// the image to process.
|
|||
/// </param>
|
|||
/// <param name="image">The current image to process</param>
|
|||
/// <param name="newImage">The new Image to return</param>
|
|||
/// <returns>
|
|||
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
|
|||
/// </returns>
|
|||
public override Image TransformImage(ImageFactory factory, Image image, Image newImage) |
|||
{ |
|||
using (Graphics graphics = Graphics.FromImage(newImage)) |
|||
{ |
|||
using (ImageAttributes attributes = new ImageAttributes()) |
|||
{ |
|||
attributes.SetColorMatrix(this.Matrix); |
|||
|
|||
Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height); |
|||
|
|||
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); |
|||
|
|||
// Add a glow to the image.
|
|||
using (GraphicsPath path = new GraphicsPath()) |
|||
{ |
|||
path.AddEllipse(rectangle); |
|||
using (PathGradientBrush brush = new PathGradientBrush(path)) |
|||
{ |
|||
// Fill a rectangle with an elliptical gradient brush that goes from orange to transparent.
|
|||
// This has the effect of painting the far corners transparent and fading in to orange on the
|
|||
// way in to the centre.
|
|||
brush.WrapMode = WrapMode.Tile; |
|||
brush.CenterColor = Color.FromArgb(70, 255, 153, 102); |
|||
brush.SurroundColors = new[] { Color.FromArgb(0, 0, 0, 0) }; |
|||
|
|||
Blend blend = new Blend |
|||
{ |
|||
Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F }, |
|||
Factors = new[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f } |
|||
}; |
|||
|
|||
brush.Blend = blend; |
|||
|
|||
Region oldClip = graphics.Clip; |
|||
graphics.Clip = new Region(rectangle); |
|||
graphics.FillRectangle(brush, rectangle); |
|||
graphics.Clip = oldClip; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Add a vignette to finish the effect.
|
|||
factory.Image = newImage; |
|||
Vignette vignette = new Vignette(); |
|||
newImage = vignette.ProcessImage(factory); |
|||
|
|||
// Reassign the image.
|
|||
image.Dispose(); |
|||
image = newImage; |
|||
|
|||
return image; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,126 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="Adjustments.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// Provides reusable adjustment methods to apply to images.
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Helpers |
|||
{ |
|||
using System; |
|||
using System.Drawing; |
|||
using System.Drawing.Imaging; |
|||
|
|||
/// <summary>
|
|||
/// Provides reusable adjustment methods to apply to images.
|
|||
/// </summary>
|
|||
public static class Adjustments |
|||
{ |
|||
/// <summary>
|
|||
/// Adjusts the brightness component of the given image.
|
|||
/// </summary>
|
|||
/// <param name="source">
|
|||
/// The <see cref="Bitmap"/> source to adjust.
|
|||
/// </param>
|
|||
/// <param name="threshold">
|
|||
/// The threshold value between -100 and 100 for adjusting the brightness.
|
|||
/// </param>
|
|||
/// <param name="rectangle">The rectangle to define the bounds of the area to adjust the brightness.
|
|||
/// If null then the effect is applied to the entire image.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Bitmap"/> with the brightness adjusted.
|
|||
/// </returns>
|
|||
/// <exception cref="ArgumentOutOfRangeException">
|
|||
/// Thrown if the threshold value falls outside the acceptable range.
|
|||
/// </exception>
|
|||
public static Bitmap Brightness(Bitmap source, int threshold, Rectangle? rectangle = null) |
|||
{ |
|||
if (threshold > 100 || threshold < -100) |
|||
{ |
|||
throw new ArgumentOutOfRangeException("threshold", "Threshold should be between -100 and 100."); |
|||
} |
|||
|
|||
float brightnessFactor = (float)threshold / 100; |
|||
Rectangle bounds = rectangle.HasValue ? rectangle.Value : new Rectangle(0, 0, source.Width, source.Height); |
|||
|
|||
ColorMatrix colorMatrix = |
|||
new ColorMatrix( |
|||
new[] |
|||
{ |
|||
new float[] { 1, 0, 0, 0, 0 }, |
|||
new float[] { 0, 1, 0, 0, 0 }, |
|||
new float[] { 0, 0, 1, 0, 0 }, |
|||
new float[] { 0, 0, 0, 1, 0 }, |
|||
new[] { brightnessFactor, brightnessFactor, brightnessFactor, 0, 1 } |
|||
}); |
|||
|
|||
using (Graphics graphics = Graphics.FromImage(source)) |
|||
{ |
|||
using (ImageAttributes imageAttributes = new ImageAttributes()) |
|||
{ |
|||
imageAttributes.SetColorMatrix(colorMatrix); |
|||
graphics.DrawImage(source, bounds, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, imageAttributes); |
|||
} |
|||
} |
|||
|
|||
return source; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adjusts the contrast component of the given image.
|
|||
/// </summary>
|
|||
/// <param name="source">
|
|||
/// The <see cref="Bitmap"/> source to adjust.
|
|||
/// </param>
|
|||
/// <param name="threshold">
|
|||
/// The threshold value between -100 and 100 for adjusting the contrast.
|
|||
/// </param>
|
|||
/// <param name="rectangle">The rectangle to define the bounds of the area to adjust the contrast.
|
|||
/// If null then the effect is applied to the entire image.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Bitmap"/> with the contrast adjusted.
|
|||
/// </returns>
|
|||
/// <exception cref="ArgumentOutOfRangeException">
|
|||
/// Thrown if the threshold value falls outside the acceptable range.
|
|||
/// </exception>
|
|||
public static Bitmap Contrast(Bitmap source, int threshold, Rectangle? rectangle = null) |
|||
{ |
|||
if (threshold > 100 || threshold < -100) |
|||
{ |
|||
throw new ArgumentOutOfRangeException("threshold", "Threshold should be between -100 and 100."); |
|||
} |
|||
|
|||
Rectangle bounds = rectangle.HasValue ? rectangle.Value : new Rectangle(0, 0, source.Width, source.Height); |
|||
|
|||
float contrastFactor = (float)threshold / 100; |
|||
|
|||
// Stop at -1 to prevent inversion.
|
|||
contrastFactor++; |
|||
float factorTransform = 0.5f * (1.0f - contrastFactor); |
|||
|
|||
ColorMatrix colorMatrix = new ColorMatrix( |
|||
new[] |
|||
{ |
|||
new[] { contrastFactor, 0, 0, 0, 0 }, |
|||
new[] { 0, contrastFactor, 0, 0, 0 }, |
|||
new[] { 0, 0, contrastFactor, 0, 0 }, |
|||
new float[] { 0, 0, 0, 1, 0 }, |
|||
new[] { factorTransform, factorTransform, factorTransform, 0, 1 } |
|||
}); |
|||
|
|||
using (Graphics graphics = Graphics.FromImage(source)) |
|||
{ |
|||
using (ImageAttributes imageAttributes = new ImageAttributes()) |
|||
{ |
|||
imageAttributes.SetColorMatrix(colorMatrix); |
|||
graphics.DrawImage(source, bounds, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, imageAttributes); |
|||
} |
|||
} |
|||
|
|||
return source; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="Effects.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// Provides reusable effect methods to apply to images.
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Helpers |
|||
{ |
|||
using System; |
|||
using System.Drawing; |
|||
using System.Drawing.Drawing2D; |
|||
|
|||
/// <summary>
|
|||
/// Provides reusable effect methods to apply to images.
|
|||
/// </summary>
|
|||
public static class Effects |
|||
{ |
|||
/// <summary>
|
|||
/// Adds a vignette effect to the source image based on the given color.
|
|||
/// </summary>
|
|||
/// <param name="source">
|
|||
/// The <see cref="Bitmap"/> source.
|
|||
/// </param>
|
|||
/// <param name="baseColor">
|
|||
/// <see cref="Color"/> to base the vignette on.
|
|||
/// </param>
|
|||
/// <param name="rectangle">
|
|||
/// The rectangle to define the bounds of the area to vignette. If null then the effect is applied
|
|||
/// to the entire image.
|
|||
/// </param>
|
|||
/// <param name="invert">
|
|||
/// Whether to invert the vignette.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="Bitmap"/> with the vignette applied.
|
|||
/// </returns>
|
|||
public static Bitmap Vignette(Bitmap source, Color baseColor, Rectangle? rectangle = null, bool invert = false) |
|||
{ |
|||
using (Graphics graphics = Graphics.FromImage(source)) |
|||
{ |
|||
Rectangle bounds = rectangle.HasValue ? rectangle.Value : new Rectangle(0, 0, source.Width, source.Height); |
|||
Rectangle ellipsebounds = bounds; |
|||
|
|||
// Increase the rectangle size by the difference between the rectangle dimensions and sqrt(2)/2 * the rectangle dimensions.
|
|||
// Why sqrt(2)/2? Because the point (sqrt(2)/2, sqrt(2)/2) is the 45 degree angle point on a unit circle. Scaling by the width
|
|||
// and height gives the distance needed to inflate the rectangle to make sure it's fully covered.
|
|||
ellipsebounds.Offset(-ellipsebounds.X, -ellipsebounds.Y); |
|||
int x = ellipsebounds.Width - (int)Math.Floor(.70712 * ellipsebounds.Width); |
|||
int y = ellipsebounds.Height - (int)Math.Floor(.70712 * ellipsebounds.Height); |
|||
ellipsebounds.Inflate(x, y); |
|||
|
|||
using (GraphicsPath path = new GraphicsPath()) |
|||
{ |
|||
path.AddEllipse(ellipsebounds); |
|||
using (PathGradientBrush brush = new PathGradientBrush(path)) |
|||
{ |
|||
// Fill a rectangle with an elliptical gradient brush that goes from transparent to opaque.
|
|||
// This has the effect of painting the far corners with the given color and shade less on the way in to the centre.
|
|||
Color centerColor; |
|||
Color edgeColor; |
|||
if (invert) |
|||
{ |
|||
centerColor = Color.FromArgb(50, baseColor.R, baseColor.G, baseColor.B); |
|||
edgeColor = Color.FromArgb(0, baseColor.R, baseColor.G, baseColor.B); |
|||
} |
|||
else |
|||
{ |
|||
centerColor = Color.FromArgb(0, baseColor.R, baseColor.G, baseColor.B); |
|||
edgeColor = Color.FromArgb(255, baseColor.R, baseColor.G, baseColor.B); |
|||
} |
|||
|
|||
brush.WrapMode = WrapMode.Tile; |
|||
brush.CenterColor = centerColor; |
|||
brush.SurroundColors = new[] { edgeColor }; |
|||
|
|||
Blend blend = new Blend |
|||
{ |
|||
Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F }, |
|||
Factors = new[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f } |
|||
}; |
|||
|
|||
brush.Blend = blend; |
|||
|
|||
Region oldClip = graphics.Clip; |
|||
graphics.Clip = new Region(bounds); |
|||
graphics.FillRectangle(brush, ellipsebounds); |
|||
graphics.Clip = oldClip; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return source; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a diffused glow (inverted vignette) effect to the source image based on the given color.
|
|||
/// </summary>
|
|||
/// <param name="source">The <see cref="Bitmap"/> source.</param>
|
|||
/// <param name="baseColor"><see cref="Color"/> to base the vignette on.</param>
|
|||
/// <param name="rectangle">The rectangle to define the bounds of the area to vignette. If null then the effect is applied
|
|||
/// to the entire image.</param>
|
|||
/// <returns>The <see cref="Bitmap"/> with the vignette applied.</returns>
|
|||
public static Bitmap Glow(Bitmap source, Color baseColor, Rectangle? rectangle = null) |
|||
{ |
|||
return Vignette(source, baseColor, rectangle, true); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
d04aa90445e483d5614cf597cbd7caa6d55d9aaa |
|||
@ -1 +0,0 @@ |
|||
e40fa501c49374e25d137627084dfa993931205f |
|||
Loading…
Reference in new issue