Browse Source

A few more parser rewrites

Former-commit-id: a3928b8cf67c7d0772097b3ed5c01eb1fc4d63d8
Former-commit-id: 584e57e966ef0c53154140ea1087551a5b89a6c2
Former-commit-id: dd3373cd83b0a915f76eadc615cfab88ffd5b548
af/merge-core
James South 11 years ago
parent
commit
64a3aef539
  1. 3
      src/ImageProcessor.Web/Helpers/ImageHelpers.cs
  2. 26
      src/ImageProcessor.Web/Helpers/QuerystringParser/GenericListTypeConverter.cs
  3. 7
      src/ImageProcessor.Web/Helpers/QuerystringParser/QueryParamParser.cs
  4. 2
      src/ImageProcessor.Web/Processors/Alpha.cs
  5. 2
      src/ImageProcessor.Web/Processors/Brightness.cs
  6. 2
      src/ImageProcessor.Web/Processors/Contrast.cs
  7. 2
      src/ImageProcessor.Web/Processors/Hue.cs
  8. 97
      src/ImageProcessor.Web/Processors/Mask.cs
  9. 24
      src/ImageProcessor.Web/Processors/Meta.cs
  10. 164
      src/ImageProcessor.Web/Processors/Overlay.cs
  11. 40
      src/ImageProcessor.Web/Processors/Pixelate.cs
  12. 30
      src/ImageProcessor.Web/Processors/Quality.cs
  13. 96
      src/ImageProcessor.Web/Processors/ReplaceColor.cs
  14. 17
      src/ImageProcessor/Common/Helpers/TypeFinder.cs
  15. 8
      src/ImageProcessor/Imaging/AnchorPosition.cs
  16. 2
      src/ImageProcessor/Processors/Mask.cs
  17. 14
      src/ImageProcessor/Processors/ReplaceColor.cs

3
src/ImageProcessor.Web/Helpers/ImageHelpers.cs

@ -10,7 +10,6 @@
namespace ImageProcessor.Web.Helpers namespace ImageProcessor.Web.Helpers
{ {
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -83,7 +82,7 @@ namespace ImageProcessor.Web.Helpers
{ {
trimmed = trimmed.Replace(queryString, string.Empty); trimmed = trimmed.Replace(queryString, string.Empty);
} }
match = FormatRegex.Match(trimmed); match = FormatRegex.Match(trimmed);
} }

26
src/ImageProcessor.Web/Helpers/QuerystringParser/GenericListTypeConverter.cs

@ -62,8 +62,7 @@ namespace ImageProcessor.Web.Helpers
{ {
if (sourceType == typeof(string)) if (sourceType == typeof(string))
{ {
string[] items = this.GetStringArray(sourceType.ToString()); return true;
return items.Any();
} }
return base.CanConvertFrom(context, sourceType); return base.CanConvertFrom(context, sourceType);
@ -89,7 +88,7 @@ namespace ImageProcessor.Web.Helpers
string input = value as string; string input = value as string;
if (input != null) if (input != null)
{ {
string[] items = this.GetStringArray(input); string[] items = this.GetStringArray(input, culture);
List<T> result = new List<T>(); List<T> result = new List<T>();
@ -136,7 +135,13 @@ namespace ImageProcessor.Web.Helpers
{ {
if (destinationType == typeof(string)) if (destinationType == typeof(string))
{ {
return string.Join(",", (IList<T>)value); if (culture == null)
{
culture = CultureInfo.CurrentCulture;
}
string separator = culture.TextInfo.ListSeparator;
return string.Join(separator, (IList<T>)value);
} }
return base.ConvertTo(context, culture, value, destinationType); return base.ConvertTo(context, culture, value, destinationType);
@ -148,12 +153,21 @@ namespace ImageProcessor.Web.Helpers
/// <param name="input"> /// <param name="input">
/// The input string to split. /// The input string to split.
/// </param> /// </param>
/// <param name="culture">
/// A <see cref="T:System.Globalization.CultureInfo"/>. The current culture to split string by.
/// </param>
/// <returns> /// <returns>
/// The <see cref="string"/> array from the comma separated values. /// The <see cref="string"/> array from the comma separated values.
/// </returns> /// </returns>
protected string[] GetStringArray(string input) protected string[] GetStringArray(string input, CultureInfo culture)
{ {
string[] result = input.Split(',').Select(s => s.Trim()).ToArray(); if (culture == null)
{
culture = CultureInfo.CurrentCulture;
}
char separator = culture.TextInfo.ListSeparator[0];
string[] result = input.Split(separator).Select(s => s.Trim()).ToArray();
return result; return result;
} }

7
src/ImageProcessor.Web/Helpers/QuerystringParser/QueryParamParser.cs

@ -17,6 +17,7 @@ namespace ImageProcessor.Web.Helpers
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Web;
/// <summary> /// <summary>
/// The query parameter parser that converts string values to different types. /// The query parameter parser that converts string values to different types.
@ -103,7 +104,7 @@ namespace ImageProcessor.Web.Helpers
try try
{ {
// ReSharper disable once AssignNullToNotNullAttribute // ReSharper disable once AssignNullToNotNullAttribute
return converter.ConvertFrom(null, culture, value); return converter.ConvertFrom(null, culture, HttpUtility.UrlDecode(value));
} }
catch catch
{ {
@ -159,6 +160,8 @@ namespace ImageProcessor.Web.Helpers
this.AddTypeConverter(typeof(List<double>), typeof(GenericListTypeConverter<double>)); this.AddTypeConverter(typeof(List<double>), typeof(GenericListTypeConverter<double>));
this.AddTypeConverter(typeof(List<string>), typeof(GenericListTypeConverter<string>)); this.AddTypeConverter(typeof(List<string>), typeof(GenericListTypeConverter<string>));
this.AddTypeConverter(typeof(List<Color>), typeof(GenericListTypeConverter<Color>));
} }
/// <summary> /// <summary>
@ -183,6 +186,8 @@ namespace ImageProcessor.Web.Helpers
this.AddTypeConverter(typeof(double[]), typeof(GenericArrayTypeConverter<double>)); this.AddTypeConverter(typeof(double[]), typeof(GenericArrayTypeConverter<double>));
this.AddTypeConverter(typeof(string[]), typeof(GenericArrayTypeConverter<string>)); this.AddTypeConverter(typeof(string[]), typeof(GenericArrayTypeConverter<string>));
this.AddTypeConverter(typeof(Color[]), typeof(GenericArrayTypeConverter<Color>));
} }
/// <summary> /// <summary>

2
src/ImageProcessor.Web/Processors/Alpha.cs

@ -27,7 +27,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"alpha=[^&]", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"alpha=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Alpha"/> class. /// Initializes a new instance of the <see cref="Alpha"/> class.

2
src/ImageProcessor.Web/Processors/Brightness.cs

@ -26,7 +26,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"brightness=[^&]", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"brightness=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Brightness"/> class. /// Initializes a new instance of the <see cref="Brightness"/> class.

2
src/ImageProcessor.Web/Processors/Contrast.cs

@ -26,7 +26,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"contrast=[^&]", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"contrast=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Contrast"/> class. /// Initializes a new instance of the <see cref="Contrast"/> class.

2
src/ImageProcessor.Web/Processors/Hue.cs

@ -29,7 +29,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"hue=[^&]", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"hue=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Hue"/> class. /// Initializes a new instance of the <see cref="Hue"/> class.

97
src/ImageProcessor.Web/Processors/Mask.cs

@ -12,14 +12,14 @@
namespace ImageProcessor.Web.Processors namespace ImageProcessor.Web.Processors
{ {
using System; using System;
using System.Collections.Specialized;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting; using System.Web.Hosting;
using ImageProcessor.Processors; using ImageProcessor.Processors;
using ImageProcessor.Web.Extensions;
using ImageProcessor.Web.Helpers; using ImageProcessor.Web.Helpers;
/// <summary> /// <summary>
@ -31,17 +31,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"(mask=|mask.\w+=)[^&]+", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"mask=[\w+-]+." + ImageHelpers.ExtensionRegexPattern);
/// <summary>
/// The mask image regex.
/// </summary>
private static readonly Regex ImageRegex = new Regex(@"mask=[\w+-]+." + ImageHelpers.ExtensionRegexPattern);
/// <summary>
/// The point regex.
/// </summary>
private static readonly Regex PointRegex = new Regex(@"mask.position=\d+,\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Mask"/> class. /// Initializes a new instance of the <see cref="Mask"/> class.
@ -81,36 +71,18 @@ namespace ImageProcessor.Web.Processors
/// </returns> /// </returns>
public int MatchRegexIndex(string queryString) public int MatchRegexIndex(string queryString)
{ {
int index = 0;
// Set the sort order to max to allow filtering.
this.SortOrder = int.MaxValue; this.SortOrder = int.MaxValue;
Match match = this.RegexPattern.Match(queryString);
// First merge the matches so we can parse . if (match.Success)
StringBuilder stringBuilder = new StringBuilder();
foreach (Match match in this.RegexPattern.Matches(queryString))
{ {
if (match.Success) this.SortOrder = match.Index;
{ NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
if (index == 0) Image image = this.ParseImage(queryCollection["mask"]);
{ Point? position = queryCollection["mask.position"] != null
// Set the index on the first instance only. ? QueryParamParser.Instance.ParseValue<Point>(queryCollection["mask.position"])
this.SortOrder = match.Index; : (Point?)null;
}
stringBuilder.Append(match.Value);
index += 1;
}
}
if (this.SortOrder < int.MaxValue)
{
// Match syntax
string toParse = stringBuilder.ToString();
Image image = this.ParseImage(toParse);
Point? position = this.ParsePoint(toParse);
this.Processor.DynamicParameter = new Tuple<Image, Point?>(image, position); this.Processor.DynamicParameter = new Tuple<Image, Point?>(image, position);
} }
@ -118,13 +90,13 @@ namespace ImageProcessor.Web.Processors
} }
/// <summary> /// <summary>
/// Returns the correct size of pixels. /// Returns an image from the given input path.
/// </summary> /// </summary>
/// <param name="input"> /// <param name="input">
/// The input containing the value to parse. /// The input containing the value to parse.
/// </param> /// </param>
/// <returns> /// <returns>
/// The <see cref="int"/> representing the pixel size. /// The <see cref="Image"/> representing the given image path.
/// </returns> /// </returns>
public Image ParseImage(string input) public Image ParseImage(string input)
{ {
@ -136,50 +108,19 @@ namespace ImageProcessor.Web.Processors
if (!string.IsNullOrWhiteSpace(path) && path.StartsWith("~/")) if (!string.IsNullOrWhiteSpace(path) && path.StartsWith("~/"))
{ {
Match match = ImageRegex.Match(input); string imagePath = HostingEnvironment.MapPath(path);
if (imagePath != null)
if (match.Success)
{ {
string imagePath = HostingEnvironment.MapPath(path); imagePath = Path.Combine(imagePath, input);
if (imagePath != null) using (ImageFactory factory = new ImageFactory())
{ {
imagePath = Path.Combine(imagePath, match.Value.Split('=')[1]); factory.Load(imagePath);
using (ImageFactory factory = new ImageFactory()) image = new Bitmap(factory.Image);
{
factory.Load(imagePath);
image = new Bitmap(factory.Image);
}
} }
} }
} }
return image; return image;
} }
/// <summary>
/// Returns the correct <see cref="Nullable{Point}"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="Nullable{Point}"/>
/// </returns>
private Point? ParsePoint(string input)
{
int[] dimensions = { };
Match match = PointRegex.Match(input);
if (match.Success)
{
dimensions = match.Value.ToPositiveIntegerArray();
}
if (dimensions.Length == 2)
{
return new Point(dimensions[0], dimensions[1]);
}
return null;
}
} }
} }

24
src/ImageProcessor.Web/Processors/Meta.cs

@ -63,27 +63,13 @@ namespace ImageProcessor.Web.Processors
/// </returns> /// </returns>
public int MatchRegexIndex(string queryString) public int MatchRegexIndex(string queryString)
{ {
int index = 0;
// Set the sort order to max to allow filtering.
this.SortOrder = int.MaxValue; this.SortOrder = int.MaxValue;
Match match = this.RegexPattern.Match(queryString);
foreach (Match match in this.RegexPattern.Matches(queryString)) if (match.Success)
{ {
if (match.Success) this.SortOrder = match.Index;
{ bool preserve = bool.Parse(match.Value.Split('=')[1]);
if (index == 0) this.Processor.DynamicParameter = preserve;
{
// Set the index on the first instance only.
this.SortOrder = match.Index;
bool preserve = bool.Parse(match.Value.Split('=')[1]);
this.Processor.DynamicParameter = preserve;
}
index += 1;
}
} }
return this.SortOrder; return this.SortOrder;

164
src/ImageProcessor.Web/Processors/Overlay.cs

@ -11,16 +11,15 @@
namespace ImageProcessor.Web.Processors namespace ImageProcessor.Web.Processors
{ {
using System; using System.Collections.Specialized;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting; using System.Web.Hosting;
using ImageProcessor.Imaging; using ImageProcessor.Imaging;
using ImageProcessor.Processors; using ImageProcessor.Processors;
using ImageProcessor.Web.Extensions;
using ImageProcessor.Web.Helpers; using ImageProcessor.Web.Helpers;
/// <summary> /// <summary>
@ -32,27 +31,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"(overlay=|overlay.\w+=)[^&]+", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"overlay=[\w+-]+." + ImageHelpers.ExtensionRegexPattern);
/// <summary>
/// The overlay image regex.
/// </summary>
private static readonly Regex ImageRegex = new Regex(@"overlay=[\w+-]+." + ImageHelpers.ExtensionRegexPattern);
/// <summary>
/// The point regex.
/// </summary>
private static readonly Regex PointRegex = new Regex(@"overlay.position=\d+,\d+", RegexOptions.Compiled);
/// <summary>
/// The size regex.
/// </summary>
private static readonly Regex SizeRegex = new Regex(@"overlay.size=\d+,\d+", RegexOptions.Compiled);
/// <summary>
/// The opacity regex.
/// </summary>
private static readonly Regex OpacityRegex = new Regex(@"overlay.opacity=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Overlay"/> class. /// Initializes a new instance of the <see cref="Overlay"/> class.
@ -92,40 +71,30 @@ namespace ImageProcessor.Web.Processors
/// </returns> /// </returns>
public int MatchRegexIndex(string queryString) public int MatchRegexIndex(string queryString)
{ {
int index = 0;
// Set the sort order to max to allow filtering.
this.SortOrder = int.MaxValue; this.SortOrder = int.MaxValue;
Match match = this.RegexPattern.Match(queryString);
// First merge the matches so we can parse . if (match.Success)
StringBuilder stringBuilder = new StringBuilder();
foreach (Match match in this.RegexPattern.Matches(queryString))
{ {
if (match.Success) this.SortOrder = match.Index;
{ NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
if (index == 0) Image image = this.ParseImage(queryCollection["overlay"]);
{
// Set the index on the first instance only. Point? position = queryCollection["overlay.position"] != null
this.SortOrder = match.Index; ? QueryParamParser.Instance.ParseValue<Point>(queryCollection["overlay.position"])
} : (Point?)null;
stringBuilder.Append(match.Value); int opacity = queryCollection["overlay.opacity"] != null
? QueryParamParser.Instance.ParseValue<int>(queryCollection["overlay.opacity"])
index += 1; : 100;
} Size size = QueryParamParser.Instance.ParseValue<Size>(queryCollection["overlay.size"]);
}
if (this.SortOrder < int.MaxValue)
{
// Match syntax
string toParse = stringBuilder.ToString();
this.Processor.DynamicParameter = new ImageLayer this.Processor.DynamicParameter = new ImageLayer
{ {
Image = this.ParseImage(toParse), Image = image,
Position = this.ParsePoint(toParse), Position = position,
Opacity = this.ParseOpacity(toParse), Opacity = opacity,
Size = this.ParseSize(toParse) Size = size
}; };
} }
@ -133,13 +102,13 @@ namespace ImageProcessor.Web.Processors
} }
/// <summary> /// <summary>
/// Returns the correct size of pixels. /// Returns an image from the given input path.
/// </summary> /// </summary>
/// <param name="input"> /// <param name="input">
/// The input containing the value to parse. /// The input containing the value to parse.
/// </param> /// </param>
/// <returns> /// <returns>
/// The <see cref="int"/> representing the pixel size. /// The <see cref="Image"/> representing the given image path.
/// </returns> /// </returns>
public Image ParseImage(string input) public Image ParseImage(string input)
{ {
@ -151,94 +120,19 @@ namespace ImageProcessor.Web.Processors
if (!string.IsNullOrWhiteSpace(path) && path.StartsWith("~/")) if (!string.IsNullOrWhiteSpace(path) && path.StartsWith("~/"))
{ {
Match match = ImageRegex.Match(input); string imagePath = HostingEnvironment.MapPath(path);
if (imagePath != null)
if (match.Success)
{ {
string imagePath = HostingEnvironment.MapPath(path); imagePath = Path.Combine(imagePath, input);
if (imagePath != null) using (ImageFactory factory = new ImageFactory())
{ {
imagePath = Path.Combine(imagePath, match.Value.Split('=')[1]); factory.Load(imagePath);
using (ImageFactory factory = new ImageFactory()) image = new Bitmap(factory.Image);
{
factory.Load(imagePath);
image = new Bitmap(factory.Image);
}
} }
} }
} }
return image; return image;
} }
/// <summary>
/// Returns the correct <see cref="Nullable{Point}"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="Nullable{Point}"/>
/// </returns>
private Point? ParsePoint(string input)
{
int[] dimensions = { };
Match match = PointRegex.Match(input);
if (match.Success)
{
dimensions = match.Value.ToPositiveIntegerArray();
}
if (dimensions.Length == 2)
{
return new Point(dimensions[0], dimensions[1]);
}
return null;
}
/// <summary>
/// Returns the correct <see cref="int"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="int"/>
/// </returns>
private int ParseOpacity(string input)
{
int opacity = 100;
Match match = OpacityRegex.Match(input);
if (match.Success)
{
opacity = Math.Abs(CommonParameterParserUtility.ParseIn100Range(match.Value.Split('=')[1]));
}
return opacity;
}
/// <summary>
/// Returns the correct <see cref="Size"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The <see cref="Size"/>.
/// </returns>
private Size ParseSize(string input)
{
Size size = Size.Empty;
Match match = SizeRegex.Match(input);
if (match.Success)
{
int[] dimensions = match.Value.ToPositiveIntegerArray();
size = new Size(dimensions[0], dimensions[1]);
}
return size;
}
} }
} }

40
src/ImageProcessor.Web/Processors/Pixelate.cs

@ -11,13 +11,16 @@
namespace ImageProcessor.Web.Processors namespace ImageProcessor.Web.Processors
{ {
using System; using System;
using System.Collections.Specialized;
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using ImageProcessor.Processors; using ImageProcessor.Processors;
using ImageProcessor.Web.Extensions; using ImageProcessor.Web.Extensions;
using ImageProcessor.Web.Helpers;
/// <summary> /// <summary>
/// Encapsulates methods to pixelate an image. /// Encapsulates methods to pixelate an image.
@ -27,7 +30,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"(pixelate=|pixelrect=)[^&]+", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"pixelate=[^&]", RegexOptions.Compiled);
/// <summary> /// <summary>
/// The pixel regex. /// The pixel regex.
@ -77,36 +80,19 @@ namespace ImageProcessor.Web.Processors
/// </returns> /// </returns>
public int MatchRegexIndex(string queryString) public int MatchRegexIndex(string queryString)
{ {
int index = 0;
// Set the sort order to max to allow filtering.
this.SortOrder = int.MaxValue; this.SortOrder = int.MaxValue;
Match match = this.RegexPattern.Match(queryString);
// First merge the matches so we can parse . if (match.Success)
StringBuilder stringBuilder = new StringBuilder();
foreach (Match match in this.RegexPattern.Matches(queryString))
{ {
if (match.Success) this.SortOrder = match.Index;
{ NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
if (index == 0) int size = QueryParamParser.Instance.ParseValue<int>(queryCollection["pixelate"]);
{
// Set the index on the first instance only. Rectangle? rectangle = queryCollection["pixelrect"] != null
this.SortOrder = match.Index; ? QueryParamParser.Instance.ParseValue<Rectangle>(queryCollection["pixelrect"])
} : (Rectangle?)null;
stringBuilder.Append(match.Value);
index += 1;
}
}
if (this.SortOrder < int.MaxValue)
{
// Match syntax
string toParse = stringBuilder.ToString();
int size = this.ParseSize(toParse);
Rectangle? rectangle = this.ParseRectangle(toParse);
this.Processor.DynamicParameter = new Tuple<int, Rectangle?>(size, rectangle); this.Processor.DynamicParameter = new Tuple<int, Rectangle?>(size, rectangle);
} }

30
src/ImageProcessor.Web/Processors/Quality.cs

@ -10,8 +10,11 @@
namespace ImageProcessor.Web.Processors namespace ImageProcessor.Web.Processors
{ {
using System; using System.Collections.Specialized;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using ImageProcessor.Imaging.Helpers;
using ImageProcessor.Processors; using ImageProcessor.Processors;
using ImageProcessor.Web.Helpers; using ImageProcessor.Web.Helpers;
@ -23,7 +26,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"quality=[^&|,]+", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"quality=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Quality"/> class. /// Initializes a new instance of the <see cref="Quality"/> class.
@ -63,25 +66,16 @@ namespace ImageProcessor.Web.Processors
/// </returns> /// </returns>
public int MatchRegexIndex(string queryString) public int MatchRegexIndex(string queryString)
{ {
int index = 0;
// Set the sort order to max to allow filtering.
this.SortOrder = int.MaxValue; this.SortOrder = int.MaxValue;
foreach (Match match in this.RegexPattern.Matches(queryString)) Match match = this.RegexPattern.Match(queryString);
if (match.Success)
{ {
if (match.Success) this.SortOrder = match.Index;
{ NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
if (index == 0) int percentage = QueryParamParser.Instance.ParseValue<int>(queryCollection["quality"]);
{ percentage = ImageMaths.Clamp(percentage, 0, 100);
// Set the index on the first instance only. this.Processor.DynamicParameter = percentage;
this.SortOrder = match.Index;
int percentage = Math.Abs(CommonParameterParserUtility.ParseIn100Range(match.Value));
this.Processor.DynamicParameter = percentage;
}
index += 1;
}
} }
return this.SortOrder; return this.SortOrder;

96
src/ImageProcessor.Web/Processors/ReplaceColor.cs

@ -11,13 +11,12 @@
namespace ImageProcessor.Web.Processors namespace ImageProcessor.Web.Processors
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Specialized;
using System.Drawing; using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using ImageProcessor.Imaging.Helpers;
using ImageProcessor.Processors; using ImageProcessor.Processors;
using ImageProcessor.Web.Helpers; using ImageProcessor.Web.Helpers;
@ -29,17 +28,7 @@ namespace ImageProcessor.Web.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"(replace=|fuzziness=)[^&]+", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"replace=[^&]", RegexOptions.Compiled);
/// <summary>
/// The replace regex.
/// </summary>
private static readonly Regex ReplaceRegex = new Regex(@"replace=[^&]+", RegexOptions.Compiled);
/// <summary>
/// The fuzz regex.
/// </summary>
private static readonly Regex FuzzRegex = new Regex(@"fuzziness=\d+", RegexOptions.Compiled);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ReplaceColor"/> class. /// Initializes a new instance of the <see cref="ReplaceColor"/> class.
@ -79,84 +68,21 @@ namespace ImageProcessor.Web.Processors
/// </returns> /// </returns>
public int MatchRegexIndex(string queryString) public int MatchRegexIndex(string queryString)
{ {
int index = 0;
// Set the sort order to max to allow filtering.
this.SortOrder = int.MaxValue; this.SortOrder = int.MaxValue;
Match match = this.RegexPattern.Match(queryString);
// First merge the matches so we can parse . if (match.Success)
StringBuilder stringBuilder = new StringBuilder();
foreach (Match match in this.RegexPattern.Matches(queryString))
{ {
if (match.Success) this.SortOrder = match.Index;
{ NameValueCollection queryCollection = HttpUtility.ParseQueryString(queryString);
if (index == 0) Color[] colors = QueryParamParser.Instance.ParseValue<Color[]>(queryCollection["replace"]);
{ int fuzziness = QueryParamParser.Instance.ParseValue<int>(queryCollection["fuzziness"]);
// Set the index on the first instance only.
this.SortOrder = match.Index;
}
stringBuilder.Append(match.Value); fuzziness = ImageMaths.Clamp(fuzziness, 0, 128);
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<Color, Color, int>(colors[0], colors[1], fuzziness); this.Processor.DynamicParameter = new Tuple<Color, Color, int>(colors[0], colors[1], fuzziness);
} }
return this.SortOrder; return this.SortOrder;
} }
/// <summary>
/// Returns the angle to alter the hue.
/// </summary>
/// <param name="input">
/// The input containing the value to parse.
/// </param>
/// <returns>
/// The <see cref="int"/> representing the angle.
/// </returns>
public Color[] ParseColor(string input)
{
IEnumerable<Color> colors = Enumerable.Empty<Color>();
Match match = ReplaceRegex.Match(input);
if (match.Success)
{
string[] colorQuery = match.Value.Split('=')[1].Split(new[] { "],[" }, StringSplitOptions.None);
colors = colorQuery.Select(s => CommonParameterParserUtility.ParseColor(s.Replace("[", string.Empty).Replace("]", string.Empty)));
}
return colors.ToArray();
}
/// <summary>
/// Returns the angle to alter the hue.
/// </summary>
/// <param name="input">
/// The input containing the value to parse.
/// </param>
/// <returns>
/// The <see cref="int"/> representing the angle.
/// </returns>
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(128, fuzziness));
}
} }
} }

17
src/ImageProcessor/Common/Helpers/TypeFinder.cs

@ -59,21 +59,18 @@ namespace ImageProcessor.Common.Helpers
{ {
"mscorlib,", "System.", "Antlr3.", "Autofac.", "mscorlib,", "System.", "Antlr3.", "Autofac.",
"Autofac,", "Castle.", "ClientDependency.", "Autofac,", "Castle.", "ClientDependency.",
"DataAnnotationsExtensions.", "DataAnnotationsExtensions.", "Dynamic,",
"DataAnnotationsExtensions,", "Dynamic,",
"HtmlDiff,", "Iesi.Collections,", "log4net,", "HtmlDiff,", "Iesi.Collections,", "log4net,",
"Microsoft.", "Newtonsoft.", "NHibernate.", "Microsoft.", "Newtonsoft.", "NHibernate.",
"NHibernate,", "NuGet.", "RouteDebugger,", "NHibernate,", "NuGet.", "RouteDebugger,",
"SqlCE4Umbraco,", "umbraco.datalayer,", "SqlCE4Umbraco,", "umbraco.",
"umbraco.interfaces,", "Lucene.", "Examine,", "AutoMapper.",
"umbraco.webservices", "Lucene.", "Examine,",
"Examine.", "ServiceStack.", "MySql.", "Examine.", "ServiceStack.", "MySql.",
"HtmlAgilityPack.", "TidyNet.", "HtmlAgilityPack.", "TidyNet.",
"ICSharpCode.", "CookComputing.", "ICSharpCode.", "CookComputing.",
"AutoMapper,", "AutoMapper.",
"AzureDirectory,", "itextsharp,", "AzureDirectory,", "itextsharp,",
"UrlRewritingNet.", "HtmlAgilityPack,", "UrlRewritingNet.", "HtmlAgilityPack,",
"MiniProfiler,", "Moq,", "nunit.framework,", "MiniProfiler,", "Moq,", "nunit.",
"TidyNet,", "WebDriver," "TidyNet,", "WebDriver,"
}; };
@ -97,8 +94,8 @@ namespace ImageProcessor.Common.Helpers
/// loaded in the CLR, not all assemblies. /// loaded in the CLR, not all assemblies.
/// See these threads: /// See these threads:
/// <see href="http://issues.umbraco.org/issue/U5-198"/> /// <see href="http://issues.umbraco.org/issue/U5-198"/>
/// <see cref="http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app"/> /// <see href="http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app"/>
/// <see cref="http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl"/> /// <see href="http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl"/>
/// </remarks> /// </remarks>
/// <returns> /// <returns>
/// The <see cref="HashSet{Assembly}"/>. /// The <see cref="HashSet{Assembly}"/>.
@ -282,7 +279,7 @@ namespace ImageProcessor.Common.Helpers
return GetAllAssemblies() return GetAllAssemblies()
.Where(x => !excludeFromResults.Contains(x) .Where(x => !excludeFromResults.Contains(x)
&& !x.GlobalAssemblyCache && !x.GlobalAssemblyCache
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f))); && !exclusionFilter.Any(f => x.FullName.StartsWith(f, StringComparison.OrdinalIgnoreCase)));
} }
} }
} }

8
src/ImageProcessor/Imaging/AnchorPosition.cs

@ -16,14 +16,14 @@ namespace ImageProcessor.Imaging
public enum AnchorPosition public enum AnchorPosition
{ {
/// <summary> /// <summary>
/// Anchors the position of the image to the top of it's bounding container. /// Anchors the position of the image to the center of it's bounding container.
/// </summary> /// </summary>
Top, Center,
/// <summary> /// <summary>
/// Anchors the position of the image to the center of it's bounding container. /// Anchors the position of the image to the top of it's bounding container.
/// </summary> /// </summary>
Center, Top,
/// <summary> /// <summary>
/// Anchors the position of the image to the bottom of it's bounding container. /// Anchors the position of the image to the bottom of it's bounding container.

2
src/ImageProcessor/Processors/Mask.cs

@ -74,7 +74,7 @@ namespace ImageProcessor.Processors
int height = image.Height; int height = image.Height;
Tuple<Image, Point?> parameters = this.DynamicParameter; Tuple<Image, Point?> parameters = this.DynamicParameter;
mask = new Bitmap(parameters.Item1); mask = new Bitmap(parameters.Item1);
Point? position = parameters.Item2.HasValue ? parameters.Item2 : null; Point? position = parameters.Item2;
if (mask.Size != image.Size) if (mask.Size != image.Size)
{ {

14
src/ImageProcessor/Processors/ReplaceColor.cs

@ -87,13 +87,11 @@ namespace ImageProcessor.Processors
using (FastBitmap fastBitmap = new FastBitmap(newImage)) using (FastBitmap fastBitmap = new FastBitmap(newImage))
{ {
//Parallel.For( Parallel.For(
// 0, 0,
// height, height,
// y => y =>
// { {
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
// Get the pixel color. // Get the pixel color.
@ -126,7 +124,7 @@ namespace ImageProcessor.Processors
} }
} }
} }
}//); });
} }
image.Dispose(); image.Dispose();

Loading…
Cancel
Save