Browse Source

Updating tests and adding rounded corners.

TODO: Finish rounded corners

Former-commit-id: 369c11006c59b8c30dd52c132d8beacbde62f475
pull/17/head
James South 12 years ago
parent
commit
d130d7e2b1
  1. 46
      src/ImageProcessor.Tests/RegularExpressionUnitTests.cs
  2. 173
      src/ImageProcessor.Web/NET45/Processors/RoundedCorners.cs
  3. 180
      src/ImageProcessor/Processors/RoundedCorners.cs

46
src/ImageProcessor.Tests/RegularExpressionUnitTests.cs

@ -8,6 +8,8 @@ namespace ImageProcessor.Tests
{
#region Using
using System.Drawing;
using ImageProcessor.Configuration;
using ImageProcessor.Imaging;
using ImageProcessor.Processors;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@ -31,10 +33,10 @@ namespace ImageProcessor.Tests
const string Querystring = "alpha=56";
const int Expected = 56;
Alpha alpha = new Alpha();
Web.Processors.Alpha alpha = new Web.Processors.Alpha();
alpha.MatchRegexIndex(Querystring);
int actual = alpha.DynamicParameter;
int actual = alpha.Processor.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
@ -48,10 +50,10 @@ namespace ImageProcessor.Tests
const string Querystring = "brightness=56";
const int Expected = 56;
Brightness brightness = new Brightness();
Web.Processors.Brightness brightness = new Web.Processors.Brightness();
brightness.MatchRegexIndex(Querystring);
int actual = brightness.DynamicParameter;
int actual = brightness.Processor.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
@ -65,10 +67,10 @@ namespace ImageProcessor.Tests
const string Querystring = "contrast=56";
const int Expected = 56;
Contrast contrast = new Contrast();
Web.Processors.Contrast contrast = new Web.Processors.Contrast();
contrast.MatchRegexIndex(Querystring);
int actual = contrast.DynamicParameter;
int actual = contrast.Processor.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
@ -82,10 +84,10 @@ namespace ImageProcessor.Tests
const string Querystring = "crop=0,0,150,300";
CropLayer expected = new CropLayer(0, 0, 150, 300, CropMode.Pixels);
Crop crop = new Crop();
Web.Processors.Crop crop = new Web.Processors.Crop();
crop.MatchRegexIndex(Querystring);
CropLayer actual = crop.DynamicParameter;
CropLayer actual = crop.Processor.DynamicParameter;
Assert.AreEqual(expected, actual);
}
@ -99,10 +101,10 @@ namespace ImageProcessor.Tests
const string Querystring = "filter=lomograph";
const string Expected = "lomograph";
Filter filter = new Filter();
Web.Processors.Filter filter = new Web.Processors.Filter();
filter.MatchRegexIndex(Querystring);
string actual = filter.DynamicParameter;
string actual = filter.Processor.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
@ -116,10 +118,10 @@ namespace ImageProcessor.Tests
const string Querystring = "format=gif";
const string Expected = "gif";
Format format = new Format();
Web.Processors.Format format = new Web.Processors.Format();
format.MatchRegexIndex(Querystring);
string actual = format.DynamicParameter;
string actual = format.Processor.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
@ -133,10 +135,10 @@ namespace ImageProcessor.Tests
const string Querystring = "quality=56";
const int Expected = 56;
Quality quality = new Quality();
Web.Processors.Quality quality = new Web.Processors.Quality();
quality.MatchRegexIndex(Querystring);
int actual = quality.DynamicParameter;
int actual = quality.Processor.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
@ -150,10 +152,10 @@ namespace ImageProcessor.Tests
const string Querystring = "width=300";
ResizeLayer expected = new ResizeLayer(new Size(300, 0));
Resize resize = new Resize();
Web.Processors.Resize resize = new Web.Processors.Resize();
resize.MatchRegexIndex(Querystring);
ResizeLayer actual = resize.DynamicParameter;
ResizeLayer actual = resize.Processor.DynamicParameter;
Assert.AreEqual(expected, actual);
}
@ -167,10 +169,10 @@ namespace ImageProcessor.Tests
const string Querystring = "rotate=270";
RotateLayer expected = new RotateLayer(270, Color.Transparent);
Rotate rotate = new Rotate();
Web.Processors.Rotate rotate = new Web.Processors.Rotate();
rotate.MatchRegexIndex(Querystring);
RotateLayer actual = rotate.DynamicParameter;
RotateLayer actual = rotate.Processor.DynamicParameter;
Assert.AreEqual(expected, actual);
}
@ -203,14 +205,14 @@ namespace ImageProcessor.Tests
Color expectedHex = ColorTranslator.FromHtml("#" + "6aa6cc");
Color expectedRgba = Color.FromArgb(255, 106, 166, 204);
Tint tint = new Tint();
Web.Processors.Tint tint = new Web.Processors.Tint();
tint.MatchRegexIndex(HexQuerystring);
Color actualHex = tint.DynamicParameter;
Color actualHex = tint.Processor.DynamicParameter;
Assert.AreEqual(expectedHex, actualHex);
tint = new Tint();
tint = new Web.Processors.Tint();
tint.MatchRegexIndex(RgbaQuerystring);
Color actualRgba = tint.DynamicParameter;
Color actualRgba = tint.Processor.DynamicParameter;
Assert.AreEqual(expectedRgba, actualRgba);
}
#endregion

173
src/ImageProcessor.Web/NET45/Processors/RoundedCorners.cs

@ -1,8 +1,10 @@

namespace ImageProcessor.Web.Processors
{
using System;
using System.Drawing;
using System.Globalization;
using System.Text.RegularExpressions;
using ImageProcessor.Imaging;
using ImageProcessor.Processors;
/// <summary>
@ -10,15 +12,180 @@ namespace ImageProcessor.Web.Processors
/// </summary>
public class RoundedCorners : IWebGraphicsProcessor
{
public Regex RegexPattern { get; private set; }
/// <summary>
/// The regular expression to search strings for.
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"roundedcorners=(\d+|[^&]*)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the angle attribute.
/// </summary>
private static readonly Regex RadiusRegex = new Regex(@"radius-(\d+)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the color attribute.
/// </summary>
private static readonly Regex ColorRegex = new Regex(@"bgcolor-([0-9a-fA-F]{3}){1,2}", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the top left attribute.
/// </summary>
private static readonly Regex TopLeftRegex = new Regex(@"tl-(true|false)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the top right attribute.
/// </summary>
private static readonly Regex TopRightRegex = new Regex(@"tr-(true|false)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the bottom left attribute.
/// </summary>
private static readonly Regex BottomLeftRegex = new Regex(@"bl-(true|false)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the bottom right attribute.
/// </summary>
private static readonly Regex BottomRightRegex = new Regex(@"br-(true|false)", RegexOptions.Compiled);
/// <summary>
/// Gets the regular expression to search strings for.
/// </summary>
public Regex RegexPattern
{
get
{
return QueryRegex;
}
}
/// <summary>
/// Gets the order in which this processor is to be used in a chain.
/// </summary>
public int SortOrder { get; private set; }
/// <summary>
/// Gets the associated graphics processor.
/// </summary>
public IGraphicsProcessor Processor { get; private set; }
/// <summary>
/// The position in the original string where the first character of the captured substring was found.
/// </summary>
/// <param name="queryString">The query string to search.</param>
/// <returns>
/// The zero-based starting position in the original string where the captured substring was found.
/// </returns>
public int MatchRegexIndex(string queryString)
{
throw new NotImplementedException();
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;
RoundedCornerLayer roundedCornerLayer;
string toParse = match.Value;
if (toParse.Contains("bgcolor"))
{
roundedCornerLayer = new RoundedCornerLayer(this.ParseRadius(toParse), this.ParseColor(toParse), this.ParseCorner(TopLeftRegex, toParse), this.ParseCorner(TopRightRegex, toParse), this.ParseCorner(BottomLeftRegex, toParse), this.ParseCorner(BottomRightRegex, toParse));
}
else
{
int radius;
int.TryParse(match.Value.Split('=')[1], NumberStyles.Any, CultureInfo.InvariantCulture, out radius);
roundedCornerLayer = new RoundedCornerLayer(radius, this.ParseCorner(TopLeftRegex, toParse), this.ParseCorner(TopRightRegex, toParse), this.ParseCorner(BottomLeftRegex, toParse), this.ParseCorner(BottomRightRegex, toParse));
}
this.Processor.DynamicParameter = roundedCornerLayer;
}
index += 1;
}
}
return this.SortOrder;
}
#region Private Methods
/// <summary>
/// Returns the correct <see cref="T:System.Int32"/> containing the radius for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="T:System.Int32"/> containing the radius for the given string.
/// </returns>
private int ParseRadius(string input)
{
foreach (Match match in RadiusRegex.Matches(input))
{
// Split on radius-
int radius;
int.TryParse(match.Value.Split('-')[1], NumberStyles.Any, CultureInfo.InvariantCulture, out radius);
return radius;
}
// No rotate - matches the RotateLayer default.
return 0;
}
/// <summary>
/// Returns the correct <see cref="T:System.Drawing.Color"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="T:System.Drawing.Color"/>
/// </returns>
private Color ParseColor(string input)
{
foreach (Match match in ColorRegex.Matches(input))
{
// split on color-hex
return ColorTranslator.FromHtml("#" + match.Value.Split('-')[1]);
}
return Color.Transparent;
}
/// <summary>
/// Returns a <see cref="T:System.Boolean"/> either true or false.
/// </summary>
/// <param name="corner">
/// The corner.
/// </param>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="T:System.Boolean"/> true or false.
/// </returns>
private bool ParseCorner(Regex corner, string input)
{
foreach (Match match in corner.Matches(input))
{
// Split on corner-
bool cornerRound;
bool.TryParse(match.Value.Split('-')[1], out cornerRound);
return cornerRound;
}
// No rotate - matches the RotateLayer default.
return true;
}
#endregion
}
}

180
src/ImageProcessor/Processors/RoundedCorners.cs

@ -24,53 +24,6 @@ namespace ImageProcessor.Processors
/// </summary>
public class RoundedCorners : IGraphicsProcessor
{
/// <summary>
/// The regular expression to search strings for.
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"roundedcorners=(\d+|[^&]*)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the angle attribute.
/// </summary>
private static readonly Regex RadiusRegex = new Regex(@"radius-(\d+)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the color attribute.
/// </summary>
private static readonly Regex ColorRegex = new Regex(@"bgcolor-([0-9a-fA-F]{3}){1,2}", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the top left attribute.
/// </summary>
private static readonly Regex TopLeftRegex = new Regex(@"tl-(true|false)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the top right attribute.
/// </summary>
private static readonly Regex TopRightRegex = new Regex(@"tr-(true|false)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the bottom left attribute.
/// </summary>
private static readonly Regex BottomLeftRegex = new Regex(@"bl-(true|false)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the bottom right attribute.
/// </summary>
private static readonly Regex BottomRightRegex = new Regex(@"br-(true|false)", RegexOptions.Compiled);
#region IGraphicsProcessor Members
/// <summary>
/// Gets the regular expression to search strings for.
/// </summary>
public Regex RegexPattern
{
get
{
return QueryRegex;
}
}
/// <summary>
/// Gets or sets DynamicParameter.
/// </summary>
@ -80,15 +33,6 @@ namespace ImageProcessor.Processors
set;
}
/// <summary>
/// Gets the order in which this processor is to be used in a chain.
/// </summary>
public int SortOrder
{
get;
private set;
}
/// <summary>
/// Gets or sets any additional settings required by the processor.
/// </summary>
@ -98,57 +42,6 @@ namespace ImageProcessor.Processors
set;
}
/// <summary>
/// The position in the original string where the first character of the captured substring was found.
/// </summary>
/// <param name="queryString">
/// The query string to search.
/// </param>
/// <returns>
/// The zero-based starting position in the original string where the captured substring was found.
/// </returns>
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;
RoundedCornerLayer roundedCornerLayer;
string toParse = match.Value;
if (toParse.Contains("bgcolor"))
{
roundedCornerLayer = new RoundedCornerLayer(this.ParseRadius(toParse), this.ParseColor(toParse), this.ParseCorner(TopLeftRegex, toParse), this.ParseCorner(TopRightRegex, toParse), this.ParseCorner(BottomLeftRegex, toParse), this.ParseCorner(BottomRightRegex, toParse));
}
else
{
int radius;
int.TryParse(match.Value.Split('=')[1], NumberStyles.Any, CultureInfo.InvariantCulture, out radius);
roundedCornerLayer = new RoundedCornerLayer(radius, this.ParseCorner(TopLeftRegex, toParse), this.ParseCorner(TopRightRegex, toParse), this.ParseCorner(BottomLeftRegex, toParse), this.ParseCorner(BottomRightRegex, toParse));
}
this.DynamicParameter = roundedCornerLayer;
}
index += 1;
}
}
return this.SortOrder;
}
/// <summary>
/// Processes the image.
/// </summary>
@ -174,7 +67,7 @@ namespace ImageProcessor.Processors
bool bottomLeft = roundedCornerLayer.BottomLeft;
bool bottomRight = roundedCornerLayer.BottomRight;
// Create a rotated image.
// Create a rounded image.
newImage = this.RoundCornerImage(image, radius, backgroundColor, topLeft, topRight, bottomLeft, bottomRight);
image.Dispose();
@ -190,9 +83,7 @@ namespace ImageProcessor.Processors
return image;
}
#endregion
#region Private Methods
/// <summary>
/// Adds rounded corners to the image
/// </summary>
@ -281,74 +172,5 @@ namespace ImageProcessor.Processors
return newImage;
}
/// <summary>
/// Returns the correct <see cref="T:System.Int32"/> containing the radius for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="T:System.Int32"/> containing the radius for the given string.
/// </returns>
private int ParseRadius(string input)
{
foreach (Match match in RadiusRegex.Matches(input))
{
// Split on radius-
int radius;
int.TryParse(match.Value.Split('-')[1], NumberStyles.Any, CultureInfo.InvariantCulture, out radius);
return radius;
}
// No rotate - matches the RotateLayer default.
return 0;
}
/// <summary>
/// Returns the correct <see cref="T:System.Drawing.Color"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="T:System.Drawing.Color"/>
/// </returns>
private Color ParseColor(string input)
{
foreach (Match match in ColorRegex.Matches(input))
{
// split on color-hex
return ColorTranslator.FromHtml("#" + match.Value.Split('-')[1]);
}
return Color.Transparent;
}
/// <summary>
/// Returns a <see cref="T:System.Boolean"/> either true or false.
/// </summary>
/// <param name="corner">
/// The corner.
/// </param>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="T:System.Boolean"/> true or false.
/// </returns>
private bool ParseCorner(Regex corner, string input)
{
foreach (Match match in corner.Matches(input))
{
// Split on corner-
bool cornerRound;
bool.TryParse(match.Value.Split('-')[1], out cornerRound);
return cornerRound;
}
// No rotate - matches the RotateLayer default.
return true;
}
#endregion
}
}

Loading…
Cancel
Save