diff --git a/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs b/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
index 77e105a59..ec9fa9e0c 100644
--- a/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
+++ b/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
@@ -118,7 +118,7 @@ namespace ImageProcessor.Helpers.Extensions
{
Contract.Requires(!string.IsNullOrWhiteSpace(expression));
- Regex regex = new Regex(@"\d+", RegexOptions.Compiled);
+ Regex regex = new Regex(@"(-|)\d+", RegexOptions.Compiled);
MatchCollection matchCollection = regex.Matches(expression);
diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs
index ab8b5ad25..90c366db7 100644
--- a/src/ImageProcessor/ImageFactory.cs
+++ b/src/ImageProcessor/ImageFactory.cs
@@ -196,7 +196,10 @@ namespace ImageProcessor
///
/// Changes the opacity of the current image.
///
- /// The percentage by which to alter the images opacity.
+ ///
+ /// The percentage by which to alter the images opacity.
+ /// Any integer between 0 and 100.
+ ///
///
/// The current instance of the class.
///
@@ -204,6 +207,12 @@ namespace ImageProcessor
{
if (this.ShouldProcess)
{
+ // Sanitize the input.
+ if (percentage > 100 || percentage < 0)
+ {
+ percentage = 0;
+ }
+
Alpha alpha = new Alpha { DynamicParameter = percentage };
this.Image = alpha.ProcessImage(this);
@@ -212,6 +221,62 @@ namespace ImageProcessor
return this;
}
+ ///
+ /// Changes the brightness of the current image.
+ ///
+ ///
+ /// The percentage by which to alter the images brightness.
+ /// Any integer between -100 and 100.
+ ///
+ ///
+ /// The current instance of the class.
+ ///
+ public ImageFactory Brightness(int percentage)
+ {
+ if (this.ShouldProcess)
+ {
+ // Sanitize the input.
+ if (percentage > 100 || percentage < -100)
+ {
+ percentage = 0;
+ }
+
+ Brightness brightness = new Brightness { DynamicParameter = percentage };
+
+ this.Image = brightness.ProcessImage(this);
+ }
+
+ return this;
+ }
+
+ ///
+ /// Changes the contrast of the current image.
+ ///
+ ///
+ /// The percentage by which to alter the images contrast.
+ /// Any integer between -100 and 100.
+ ///
+ ///
+ /// The current instance of the class.
+ ///
+ public ImageFactory Contrast(int percentage)
+ {
+ if (this.ShouldProcess)
+ {
+ // Sanitize the input.
+ if (percentage > 100 || percentage < -100)
+ {
+ percentage = 0;
+ }
+
+ Contrast contrast = new Contrast { DynamicParameter = percentage };
+
+ this.Image = contrast.ProcessImage(this);
+ }
+
+ return this;
+ }
+
///
/// Crops an image to the given coordinates.
///
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index f28352c9e..204c0a126 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -110,6 +110,8 @@
+
+
diff --git a/src/ImageProcessor/Processors/Brightness.cs b/src/ImageProcessor/Processors/Brightness.cs
new file mode 100644
index 000000000..676e819bb
--- /dev/null
+++ b/src/ImageProcessor/Processors/Brightness.cs
@@ -0,0 +1,185 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+// -----------------------------------------------------------------------
+
+namespace ImageProcessor.Processors
+{
+ #region Using
+ using System.Collections.Generic;
+ using System.Drawing;
+ using System.Drawing.Imaging;
+ using System.Text.RegularExpressions;
+ using ImageProcessor.Helpers.Extensions;
+ #endregion
+
+ ///
+ /// Encapsulates methods to change the brightness component of the image.
+ ///
+ public class Brightness : IGraphicsProcessor
+ {
+ ///
+ /// The regular expression to search strings for.
+ ///
+ ///
+ private static readonly Regex QueryRegex = new Regex(@"brightness=(-|)(?:100|[1-9]?[0-9])", RegexOptions.Compiled);
+
+ #region IGraphicsProcessor Members
+ ///
+ /// Gets the name.
+ ///
+ public string Name
+ {
+ get
+ {
+ return "Brightness";
+ }
+ }
+
+ ///
+ /// Gets the description.
+ ///
+ public string Description
+ {
+ get
+ {
+ return "Changes the the brightness component of the image.";
+ }
+ }
+
+ ///
+ /// Gets the regular expression to search strings for.
+ ///
+ public Regex RegexPattern
+ {
+ get
+ {
+ return QueryRegex;
+ }
+ }
+
+ ///
+ /// Gets or sets DynamicParameter.
+ ///
+ public dynamic DynamicParameter
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets the order in which this processor is to be used in a chain.
+ ///
+ public int SortOrder
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Gets or sets any additional settings required by the processor.
+ ///
+ public Dictionary Settings
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The position in the original string where the first character of the captured substring was found.
+ ///
+ ///
+ /// The query string to search.
+ ///
+ ///
+ /// The zero-based starting position in the original string where the captured substring was found.
+ ///
+ public int MatchRegexIndex(string queryString)
+ {
+ int index = 0;
+
+ // Set the sort order to max to allow filtering.
+ this.SortOrder = int.MaxValue;
+
+ foreach (Match match in this.RegexPattern.Matches(queryString))
+ {
+ if (match.Success)
+ {
+ if (index == 0)
+ {
+ // Set the index on the first instance only.
+ this.SortOrder = match.Index;
+ int percentage = match.Value.ToIntegerArray()[0];
+
+ this.DynamicParameter = percentage;
+ }
+
+ index += 1;
+ }
+ }
+
+ return this.SortOrder;
+ }
+
+ ///
+ /// Processes the image.
+ ///
+ ///
+ /// The the current instance of the class containing
+ /// the image to process.
+ ///
+ ///
+ /// The processed image from the current instance of the class.
+ ///
+ public Image ProcessImage(ImageFactory factory)
+ {
+ Bitmap newImage = null;
+ Image image = factory.Image;
+
+ try
+ {
+ float brightnessFactor = (float)this.DynamicParameter / 100;
+
+ // Dont use an object initializer here.
+ newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb);
+ newImage.Tag = image.Tag;
+
+ ColorMatrix colorMatrix = new ColorMatrix(
+ new float[][]
+ {
+ 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 float[] { brightnessFactor, brightnessFactor, brightnessFactor, 0, 1 }
+ });
+
+
+ using (Graphics graphics = Graphics.FromImage(newImage))
+ {
+ using (ImageAttributes imageAttributes = new ImageAttributes())
+ {
+ imageAttributes.SetColorMatrix(colorMatrix);
+
+ graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes);
+
+ image.Dispose();
+ image = newImage;
+ }
+ }
+ }
+ catch
+ {
+ if (newImage != null)
+ {
+ newImage.Dispose();
+ }
+ }
+
+ return image;
+ }
+ #endregion
+ }
+}
diff --git a/src/ImageProcessor/Processors/Contrast.cs b/src/ImageProcessor/Processors/Contrast.cs
new file mode 100644
index 000000000..2259cc3a2
--- /dev/null
+++ b/src/ImageProcessor/Processors/Contrast.cs
@@ -0,0 +1,188 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+// -----------------------------------------------------------------------
+
+namespace ImageProcessor.Processors
+{
+ #region Using
+ using System.Collections.Generic;
+ using System.Drawing;
+ using System.Drawing.Imaging;
+ using System.Text.RegularExpressions;
+ using ImageProcessor.Helpers.Extensions;
+ #endregion
+
+ ///
+ /// Encapsulates methods to change the contrast component of the image.
+ ///
+ public class Contrast : IGraphicsProcessor
+ {
+ ///
+ /// The regular expression to search strings for.
+ ///
+ ///
+ private static readonly Regex QueryRegex = new Regex(@"contrast=(-|)(?:100|[1-9]?[0-9])", RegexOptions.Compiled);
+
+ #region IGraphicsProcessor Members
+ ///
+ /// Gets the name.
+ ///
+ public string Name
+ {
+ get
+ {
+ return "Contrast";
+ }
+ }
+
+ ///
+ /// Gets the description.
+ ///
+ public string Description
+ {
+ get
+ {
+ return "Changes the the contrast component of the image.";
+ }
+ }
+
+ ///
+ /// Gets the regular expression to search strings for.
+ ///
+ public Regex RegexPattern
+ {
+ get
+ {
+ return QueryRegex;
+ }
+ }
+
+ ///
+ /// Gets or sets DynamicParameter.
+ ///
+ public dynamic DynamicParameter
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets the order in which this processor is to be used in a chain.
+ ///
+ public int SortOrder
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Gets or sets any additional settings required by the processor.
+ ///
+ public Dictionary Settings
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The position in the original string where the first character of the captured substring was found.
+ ///
+ ///
+ /// The query string to search.
+ ///
+ ///
+ /// The zero-based starting position in the original string where the captured substring was found.
+ ///
+ public int MatchRegexIndex(string queryString)
+ {
+ int index = 0;
+
+ // Set the sort order to max to allow filtering.
+ this.SortOrder = int.MaxValue;
+
+ foreach (Match match in this.RegexPattern.Matches(queryString))
+ {
+ if (match.Success)
+ {
+ if (index == 0)
+ {
+ // Set the index on the first instance only.
+ this.SortOrder = match.Index;
+ int percentage = match.Value.ToIntegerArray()[0];
+
+ this.DynamicParameter = percentage;
+ }
+
+ index += 1;
+ }
+ }
+
+ return this.SortOrder;
+ }
+
+ ///
+ /// Processes the image.
+ ///
+ ///
+ /// The the current instance of the class containing
+ /// the image to process.
+ ///
+ ///
+ /// The processed image from the current instance of the class.
+ ///
+ public Image ProcessImage(ImageFactory factory)
+ {
+ Bitmap newImage = null;
+ Image image = factory.Image;
+
+ try
+ {
+ float contrastFactor = (float)this.DynamicParameter / 100;
+
+ // Stop at -1 to prevent inversion.
+ contrastFactor++;
+ float factorTransform = 0.5f * (1.0f - contrastFactor);
+
+ // Dont use an object initializer here.
+ newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb);
+ newImage.Tag = image.Tag;
+
+ ColorMatrix colorMatrix = new ColorMatrix(
+ new float[][]
+ {
+ new float[] { contrastFactor, 0, 0, 0, 0 },
+ new float[] { 0, contrastFactor, 0, 0, 0 },
+ new float[] { 0, 0, contrastFactor, 0, 0 },
+ new float[] { 0, 0, 0, 1, 0 },
+ new float[] { factorTransform, factorTransform, factorTransform, 0, 1 }
+ });
+
+ using (Graphics graphics = Graphics.FromImage(newImage))
+ {
+ using (ImageAttributes imageAttributes = new ImageAttributes())
+ {
+ imageAttributes.SetColorMatrix(colorMatrix);
+
+ graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes);
+
+ image.Dispose();
+ image = newImage;
+ }
+ }
+ }
+ catch
+ {
+ if (newImage != null)
+ {
+ newImage.Dispose();
+ }
+ }
+
+ return image;
+ }
+ #endregion
+ }
+}