diff --git a/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs b/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs
index 13ac2b01b..963cd1b82 100644
--- a/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs
+++ b/src/ImageProcessor.Web.UnitTests/RegularExpressionUnitTests.cs
@@ -290,14 +290,14 @@ namespace ImageProcessor.Web.UnitTests
[Test]
[TestCase("rotate=0", 0F)]
[TestCase("rotate=270", 270F)]
- [TestCase("rotate=-270", 0F)]
+ [TestCase("rotate=-270", -270F)]
[TestCase("rotate=angle-28", 28F)]
- public void TestRotateRegex(string input, int expected)
+ public void TestRotateRegex(string input, float expected)
{
Processors.Rotate rotate = new Processors.Rotate();
rotate.MatchRegexIndex(input);
- int result = rotate.Processor.DynamicParameter;
+ float result = rotate.Processor.DynamicParameter;
Assert.AreEqual(expected, result);
}
diff --git a/src/ImageProcessor.Web/Configuration/Resources/processing.config b/src/ImageProcessor.Web/Configuration/Resources/processing.config
index c178f04cf..ab0eb300a 100644
--- a/src/ImageProcessor.Web/Configuration/Resources/processing.config
+++ b/src/ImageProcessor.Web/Configuration/Resources/processing.config
@@ -36,6 +36,7 @@
+
diff --git a/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs b/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs
index 44f8c20cd..47dd1f1f1 100644
--- a/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs
+++ b/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs
@@ -102,7 +102,7 @@ namespace ImageProcessor.Web.Helpers
{
foreach (Match match in ColorRegex.Matches(input))
{
- string value = match.Value.Split(new[] { '=', '-' })[1];
+ string value = match.Value;
if (KnownColors.ContainsKey(value))
{
@@ -250,7 +250,7 @@ namespace ImageProcessor.Web.Helpers
private static Regex BuildColorRegex()
{
StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.Append(@"(bgcolor|color|tint|vignette)(=|-)(\d+,\d+,\d+,\d+|([0-9a-fA-F]{3}){1,2}|(");
+ stringBuilder.Append(@"(\d+,\d+,\d+,\d+|([0-9a-fA-F]{3}){1,2}|(");
KnownColor[] knownColors = (KnownColor[])Enum.GetValues(typeof(KnownColor));
diff --git a/src/ImageProcessor.Web/ImageProcessor.Web.csproj b/src/ImageProcessor.Web/ImageProcessor.Web.csproj
index 589ef0359..7859ba25a 100644
--- a/src/ImageProcessor.Web/ImageProcessor.Web.csproj
+++ b/src/ImageProcessor.Web/ImageProcessor.Web.csproj
@@ -51,6 +51,7 @@
+
diff --git a/src/ImageProcessor.Web/Processors/BackgroundColor.cs b/src/ImageProcessor.Web/Processors/BackgroundColor.cs
index edc9c3b68..e8e88dd55 100644
--- a/src/ImageProcessor.Web/Processors/BackgroundColor.cs
+++ b/src/ImageProcessor.Web/Processors/BackgroundColor.cs
@@ -75,7 +75,7 @@ namespace ImageProcessor.Web.Processors
{
// Set the index on the first instance only.
this.SortOrder = match.Index;
- this.Processor.DynamicParameter = CommonParameterParserUtility.ParseColor(match.Value);
+ this.Processor.DynamicParameter = CommonParameterParserUtility.ParseColor(match.Value.Split(new[] { '=', '-' })[1]);
}
index += 1;
diff --git a/src/ImageProcessor.Web/Processors/ReplaceColor.cs b/src/ImageProcessor.Web/Processors/ReplaceColor.cs
new file mode 100644
index 000000000..286852624
--- /dev/null
+++ b/src/ImageProcessor.Web/Processors/ReplaceColor.cs
@@ -0,0 +1,162 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Encapsulates methods allowing the replacement of a color within an image.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Processors
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Drawing;
+ using System.Globalization;
+ using System.Linq;
+ using System.Text;
+ using System.Text.RegularExpressions;
+
+ using ImageProcessor.Processors;
+ using ImageProcessor.Web.Helpers;
+
+ ///
+ /// Encapsulates methods allowing the replacement of a color within an image.
+ ///
+ public class ReplaceColor : IWebGraphicsProcessor
+ {
+ ///
+ /// The regular expression to search strings for.
+ ///
+ private static readonly Regex QueryRegex = new Regex(@"(replace=|fuzziness=)[^&]+", RegexOptions.Compiled);
+
+ ///
+ /// The replace regex.
+ ///
+ private static readonly Regex ReplaceRegex = new Regex(@"replace=[^&]+", RegexOptions.Compiled);
+
+ ///
+ /// The fuzz regex.
+ ///
+ private static readonly Regex FuzzRegex = new Regex(@"fuzziness=\d+", RegexOptions.Compiled);
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ReplaceColor()
+ {
+ this.Processor = new ImageProcessor.Processors.ReplaceColor();
+ }
+
+ ///
+ /// Gets the regular expression to search strings for.
+ ///
+ public Regex RegexPattern
+ {
+ get
+ {
+ return QueryRegex;
+ }
+ }
+
+ ///
+ /// Gets the order in which this processor is to be used in a chain.
+ ///
+ public int SortOrder { get; private set; }
+
+ ///
+ /// Gets the associated graphics processor.
+ ///
+ public IGraphicsProcessor Processor { get; private 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;
+
+ // First merge the matches so we can parse .
+ StringBuilder stringBuilder = new StringBuilder();
+
+ 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;
+ }
+
+ stringBuilder.Append(match.Value);
+
+ index += 1;
+ }
+ }
+
+ if (this.SortOrder < int.MaxValue)
+ {
+ // Match syntax
+ string toParse = stringBuilder.ToString();
+ Color[] colors = this.ParseColor(toParse);
+ int fuzziness = this.ParseFuzziness(toParse);
+ this.Processor.DynamicParameter = new Tuple(colors[0], colors[1], fuzziness);
+ }
+
+ return this.SortOrder;
+ }
+
+ ///
+ /// Returns the angle to alter the hue.
+ ///
+ ///
+ /// The input containing the value to parse.
+ ///
+ ///
+ /// The representing the angle.
+ ///
+ public Color[] ParseColor(string input)
+ {
+ IEnumerable colors = Enumerable.Empty();
+ Match match = ReplaceRegex.Match(input);
+ if (match.Success)
+ {
+ string[] colorQuery = match.Value.Split('=')[1].Split('|');
+ colors = colorQuery.Select(CommonParameterParserUtility.ParseColor);
+ }
+
+ return colors.ToArray();
+ }
+
+ ///
+ /// Returns the angle to alter the hue.
+ ///
+ ///
+ /// The input containing the value to parse.
+ ///
+ ///
+ /// The representing the angle.
+ ///
+ public int ParseFuzziness(string input)
+ {
+ int fuzziness = 0;
+
+ Match match = FuzzRegex.Match(input);
+ if (match.Success)
+ {
+ fuzziness = int.Parse(match.Value.Split('=')[1], CultureInfo.InvariantCulture);
+ }
+
+ return Math.Max(0, Math.Min(100, fuzziness));
+ }
+ }
+}
diff --git a/src/ImageProcessor.Web/Processors/Tint.cs b/src/ImageProcessor.Web/Processors/Tint.cs
index 73fef8b3f..f8cce6b6e 100644
--- a/src/ImageProcessor.Web/Processors/Tint.cs
+++ b/src/ImageProcessor.Web/Processors/Tint.cs
@@ -72,7 +72,7 @@ namespace ImageProcessor.Web.Processors
{
// Set the index on the first instance only.
this.SortOrder = match.Index;
- this.Processor.DynamicParameter = CommonParameterParserUtility.ParseColor(match.Value);
+ this.Processor.DynamicParameter = CommonParameterParserUtility.ParseColor(match.Value.Split('=')[1]);
}
index += 1;
diff --git a/src/ImageProcessor.Web/Processors/Vignette.cs b/src/ImageProcessor.Web/Processors/Vignette.cs
index 7dc7259d3..56b67f6e1 100644
--- a/src/ImageProcessor.Web/Processors/Vignette.cs
+++ b/src/ImageProcessor.Web/Processors/Vignette.cs
@@ -79,7 +79,7 @@ namespace ImageProcessor.Web.Processors
// Set the index on the first instance only.
this.SortOrder = match.Index;
- Color color = CommonParameterParserUtility.ParseColor(match.Value);
+ Color color = CommonParameterParserUtility.ParseColor(match.Value.Split('=')[1]);
if (color.Equals(Color.Transparent))
{
color = Color.Black;
diff --git a/src/ImageProcessor.Web/Processors/Watermark.cs b/src/ImageProcessor.Web/Processors/Watermark.cs
index 0e2afa126..b5842ea7e 100644
--- a/src/ImageProcessor.Web/Processors/Watermark.cs
+++ b/src/ImageProcessor.Web/Processors/Watermark.cs
@@ -66,6 +66,11 @@ namespace ImageProcessor.Web.Processors
///
private static readonly Regex ShadowRegex = new Regex(@"((text|font|drop)?)shadow(=|-)true", RegexOptions.Compiled);
+ ///
+ /// The regular expression to search strings for the color attribute.
+ ///
+ private static readonly Regex ColorRegex = new Regex(@"color(=|-)[^&]+", RegexOptions.Compiled);
+
///
/// Initializes a new instance of the class.
///
@@ -202,12 +207,18 @@ namespace ImageProcessor.Web.Processors
///
private Color ParseColor(string input)
{
- Color textColor = CommonParameterParserUtility.ParseColor(input);
- if (!textColor.Equals(Color.Transparent))
+ foreach (Match match in ColorRegex.Matches(input))
{
- return textColor;
+ string value = match.Value.Split(new[] { '=', '-' })[1];
+ Color textColor = CommonParameterParserUtility.ParseColor(value);
+ if (!textColor.Equals(Color.Transparent))
+ {
+ return textColor;
+ }
}
+
+
return Color.Black;
}