diff --git a/src/ImageProcessor.Web/Properties/AssemblyInfo.cs b/src/ImageProcessor.Web/Properties/AssemblyInfo.cs
index 56fb6e850..d1564391c 100644
--- a/src/ImageProcessor.Web/Properties/AssemblyInfo.cs
+++ b/src/ImageProcessor.Web/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.2.0")]
-[assembly: AssemblyFileVersion("1.0.2.0")]
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs
index 69b0a7556..69fd0fc91 100644
--- a/src/ImageProcessor/ImageFactory.cs
+++ b/src/ImageProcessor/ImageFactory.cs
@@ -312,15 +312,33 @@ namespace ImageProcessor
///
/// Rotates the current image by the given angle.
///
- /// The angle by which to rotate the image.
+ ///
+ /// The angle by which to rotate the image.
+ ///
+ ///
+ /// The background Colour.
+ ///
///
/// The current instance of the class.
///
- public ImageFactory Rotate(int angle)
+ public ImageFactory Rotate(int angle, Color backgroundColour = default(Color))
{
if (this.ShouldProcess)
{
- Rotate rotate = new Rotate { DynamicParameter = angle };
+ // Sanitize the input.
+ if (angle > 360 || angle < 0)
+ {
+ angle = 0;
+ }
+
+ RotateLayer rotateLayer = new RotateLayer { Angle = angle };
+
+ if (backgroundColour != default(Color))
+ {
+ rotateLayer.BackgroundColor = backgroundColour;
+ }
+
+ Rotate rotate = new Rotate { DynamicParameter = rotateLayer };
this.Image = rotate.ProcessImage(this);
}
@@ -385,7 +403,7 @@ namespace ImageProcessor
// Fix the colour palette of gif images.
this.FixGifs();
- if (this.ImageFormat == ImageFormat.Jpeg)
+ if (object.Equals(this.ImageFormat, ImageFormat.Jpeg))
{
// Jpegs can be saved with different settings to include a quality setting for the JPEG compression.
// This improves output compression and quality.
@@ -418,7 +436,7 @@ namespace ImageProcessor
// Fix the colour palette of gif images.
this.FixGifs();
- if (this.ImageFormat == ImageFormat.Jpeg)
+ if (object.Equals(this.ImageFormat, ImageFormat.Jpeg))
{
// Jpegs can be saved with different settings to include a quality setting for the JPEG compression.
// This improves output compression and quality.
@@ -500,7 +518,7 @@ namespace ImageProcessor
{
// Fix the colour palette of gif images.
// TODO: Why does the palette not get fixed when resized to the same dimensions.
- if (this.ImageFormat == ImageFormat.Gif)
+ if (object.Equals(this.ImageFormat, ImageFormat.Gif))
{
OctreeQuantizer quantizer = new OctreeQuantizer(255, 8);
this.Image = quantizer.Quantize(this.Image);
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index 5eee94bd0..56c0e84a7 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -76,6 +76,7 @@
+
diff --git a/src/ImageProcessor/ImageProcessor.sln b/src/ImageProcessor/ImageProcessor.sln
index 35a90a6e6..a6b3bf630 100644
--- a/src/ImageProcessor/ImageProcessor.sln
+++ b/src/ImageProcessor/ImageProcessor.sln
@@ -1,6 +1,6 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor", "ImageProcessor.csproj", "{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "..\Test\Test\Test.csproj", "{30327C08-7574-4D7E-AC95-6A58753C6855}"
diff --git a/src/ImageProcessor/Imaging/RotateLayer.cs b/src/ImageProcessor/Imaging/RotateLayer.cs
new file mode 100644
index 000000000..80cc52168
--- /dev/null
+++ b/src/ImageProcessor/Imaging/RotateLayer.cs
@@ -0,0 +1,40 @@
+// -----------------------------------------------------------------------
+//
+// TODO: Update copyright text.
+//
+// -----------------------------------------------------------------------
+
+namespace ImageProcessor.Imaging
+{
+ #region Using
+ using System.Drawing;
+ #endregion
+
+ ///
+ /// Enacapsulates the properties required to rotate an image.
+ ///
+ internal class RotateLayer
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public RotateLayer()
+ {
+ this.BackgroundColor = Color.Transparent;
+ }
+ #endregion
+
+ #region Properties
+ ///
+ /// Gets or sets the angle at which to rotate the image.
+ ///
+ public int Angle { get; set; }
+
+ ///
+ /// Gets or sets the background color.
+ ///
+ public Color BackgroundColor { get; set; }
+ #endregion
+ }
+}
diff --git a/src/ImageProcessor/Processors/Filter.cs b/src/ImageProcessor/Processors/Filter.cs
index f1aec4f94..bad5e7552 100644
--- a/src/ImageProcessor/Processors/Filter.cs
+++ b/src/ImageProcessor/Processors/Filter.cs
@@ -7,18 +7,11 @@
namespace ImageProcessor.Processors
{
#region Using
-
- using System;
using System.Collections.Generic;
using System.Drawing;
- using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
- using System.IO;
using System.Text.RegularExpressions;
- using System.Web;
- using System.Web.Hosting;
using ImageProcessor.Imaging.Filters;
-
#endregion
///
@@ -183,8 +176,10 @@ namespace ImageProcessor.Processors
break;
}
- return matrix.ProcessImage(factory, image, newImage);
-
+ if (matrix != null)
+ {
+ return matrix.ProcessImage(factory, image, newImage);
+ }
}
catch
{
diff --git a/src/ImageProcessor/Processors/Rotate.cs b/src/ImageProcessor/Processors/Rotate.cs
index e8161ef30..560d110f6 100644
--- a/src/ImageProcessor/Processors/Rotate.cs
+++ b/src/ImageProcessor/Processors/Rotate.cs
@@ -7,13 +7,12 @@
namespace ImageProcessor.Processors
{
#region Using
+ using System;
using System.Collections.Generic;
using System.Drawing;
- using System.Drawing.Imaging;
- using System.Text.RegularExpressions;
- using ImageProcessor.Helpers.Extensions;
- using System;
using System.Drawing.Drawing2D;
+ using System.Text.RegularExpressions;
+ using ImageProcessor.Imaging;
#endregion
///
@@ -24,24 +23,18 @@ namespace ImageProcessor.Processors
///
/// The regular expression to search strings for.
///
- //private static readonly Regex QueryRegex = new Regex(@"rotate=-*([1-9][0-7][0-9]|\d{1,2}(?!\d)|180)|rotate=[^&]*", RegexOptions.Compiled);
- private static readonly Regex QueryRegex = new Regex(@"rotate=-*([1-2][0-9][0-9]|3[0-5][0-9]|\d{1}(?!\d)|\d{1,2}(?!\d)|360)|rotate=[^&]*", RegexOptions.Compiled);
+ private static readonly Regex QueryRegex = new Regex(@"rotate=([1-2][0-9][0-9]|3[0-5][0-9]|\d{1}(?!\d)|\d{1,2}(?!\d)|360)|rotate=[^&]*", RegexOptions.Compiled);
///
/// The regular expression to search strings for the angle attribute.
///
- private static readonly Regex AngleRegex = new Regex(@"rotate=\[-*([1-9][0-7][0-9]|\d{1,2}(?!\d)|180)\]", RegexOptions.Compiled);
+ private static readonly Regex AngleRegex = new Regex(@"rotate=angle-\[([1-2][0-9][0-9]|3[0-5][0-9]|\d{1}(?!\d)|\d{1,2}(?!\d)|360)\]", RegexOptions.Compiled);
///
/// The regular expression to search strings for the color attribute.
///
private static readonly Regex ColorRegex = new Regex(@"bgcolor-([0-9a-fA-F]{3}){1,2}", RegexOptions.Compiled);
- ///
- /// The format of the image to rotate.
- ///
- private ImageFormat imageFormat;
-
#region IGraphicsProcessor Members
///
/// Gets the name.
@@ -127,11 +120,25 @@ namespace ImageProcessor.Processors
{
// Set the index on the first instance only.
this.SortOrder = match.Index;
- int degrees;
- int.TryParse(match.Value.Split('=')[1], out degrees);
+ RotateLayer rotateLayer = new RotateLayer();
+
+ string toParse = match.Value;
+
+ if (toParse.Contains("bgcolor"))
+ {
+ rotateLayer.Angle = this.ParseAngle(toParse);
+ rotateLayer.BackgroundColor = this.ParseColor(toParse);
+ }
+ else
+ {
+ int degrees;
+ int.TryParse(match.Value.Split('=')[1], out degrees);
+
+ rotateLayer.Angle = degrees;
+ }
- this.DynamicParameter = degrees;
+ this.DynamicParameter = rotateLayer;
}
index += 1;
@@ -158,21 +165,20 @@ namespace ImageProcessor.Processors
try
{
- int angle = this.DynamicParameter;
+ RotateLayer rotateLayer = this.DynamicParameter;
+ int angle = rotateLayer.Angle;
+ Color backgroundColor = rotateLayer.BackgroundColor;
// Center of the image
- float rotateAtX = image.Width / 2;
- float rotateAtY = image.Height / 2;
-
- this.imageFormat = factory.ImageFormat;
+ float rotateAtX = Math.Abs(image.Width / 2);
+ float rotateAtY = Math.Abs(image.Height / 2);
// Create a rotated image.
- newImage = RotateImage(image, rotateAtX, rotateAtY, angle);
+ newImage = this.RotateImage(image, rotateAtX, rotateAtY, angle, backgroundColor);
newImage.Tag = image.Tag;
image.Dispose();
image = newImage;
-
}
catch
{
@@ -186,67 +192,71 @@ namespace ImageProcessor.Processors
}
#endregion
+ #region Private Methods
///
- ///
+ /// Rotates an image to the given angle at the given position.
///
- ///
- ///
- ///
- ///
- ///
- /// Based on http://www.codeproject.com/Articles/58815/C-Image-PictureBox-Rotations?msg=4155374#xx4155374xx
- private Bitmap RotateImage(Image image, float rotateAtX, float rotateAtY, float angle)
+ /// The image to rotate
+ /// The horizontal pixel coordinate at which to rotate the image.
+ /// The vertical pixel coordinate at which to rotate the image.
+ /// The angle in degress at which to rotate the image.
+ /// The background color to fill an image with.
+ /// The image rotated to the given angle at the given position.
+ ///
+ /// Based on http://www.codeproject.com/Articles/58815/C-Image-PictureBox-Rotations?msg=4155374#xx4155374xx
+ ///
+ private Bitmap RotateImage(Image image, float rotateAtX, float rotateAtY, float angle, Color backgroundColor)
{
- int width, height, X, Y;
+ int width, height, x, y;
// Degrees to radians according to Google.
- const double degreeToRadian = 0.0174532925;
+ const double DegreeToRadian = 0.0174532925;
- double widthAsDouble = (double)image.Width;
- double heightAsDouble = (double)image.Height;
+ double widthAsDouble = image.Width;
+ double heightAsDouble = image.Height;
// Allow for angles over 180
if (angle > 180)
{
angle = angle - 360;
- }
+ }
- double degrees = Math.Abs(angle);
+ double degrees = Math.Abs(angle);
if (degrees <= 90)
{
- double radians = degreeToRadian * degrees;
+ double radians = DegreeToRadian * degrees;
double radiansSin = Math.Sin(radians);
double radiansCos = Math.Cos(radians);
- width = (int)(heightAsDouble * radiansSin + widthAsDouble * radiansCos);
- height = (int)(widthAsDouble * radiansSin + heightAsDouble * radiansCos);
- X = (width - image.Width) / 2;
- Y = (height - image.Height) / 2;
+ width = (int)((heightAsDouble * radiansSin) + (widthAsDouble * radiansCos));
+ height = (int)((widthAsDouble * radiansSin) + (heightAsDouble * radiansCos));
+ x = (width - image.Width) / 2;
+ y = (height - image.Height) / 2;
}
else
{
degrees -= 90;
- double radians = degreeToRadian * degrees;
+ double radians = DegreeToRadian * degrees;
double radiansSin = Math.Sin(radians);
double radiansCos = Math.Cos(radians);
- // Fix the 270 bug
- if (radiansCos == -1)
+ // Fix the 270 error
+ if (Math.Abs(radiansCos - -1.0D) < 0.00001)
{
- radiansCos = -1 * -1;
+ radiansCos = 1;
}
- width = (int)(widthAsDouble * radiansSin + heightAsDouble * radiansCos);
- height = (int)(heightAsDouble * radiansSin + widthAsDouble * radiansCos);
- X = (width - image.Width) / 2;
- Y = (height - image.Height) / 2;
+ width = (int)((widthAsDouble * radiansSin) + (heightAsDouble * radiansCos));
+ height = (int)((heightAsDouble * radiansSin) + (widthAsDouble * radiansCos));
+ x = (width - image.Width) / 2;
+ y = (height - image.Height) / 2;
}
- //create a new empty bitmap to hold rotated image
+ // Create a new empty bitmap to hold rotated image
Bitmap newImage = new Bitmap(width, height);
newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
- //make a graphics object from the empty bitmap
+ // Make a graphics object from the empty bitmap
using (Graphics graphics = Graphics.FromImage(newImage))
{
// Reduce the jagged edge.
@@ -257,26 +267,67 @@ namespace ImageProcessor.Processors
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
- // Fill the background TODO: Set a color
- if (this.imageFormat == ImageFormat.Jpeg)
- {
- graphics.Clear(Color.White);
- }
+ // Fill the background.
+ graphics.Clear(backgroundColor);
// Put the rotation point in the "center" of the image
- graphics.TranslateTransform(rotateAtX + X, rotateAtY + Y);
+ graphics.TranslateTransform(rotateAtX + x, rotateAtY + y);
// Rotate the image
graphics.RotateTransform(angle);
// Move the image back
- graphics.TranslateTransform(-rotateAtX - X, -rotateAtY - Y);
+ graphics.TranslateTransform(-rotateAtX - x, -rotateAtY - y);
// Draw passed in image onto graphics object
- graphics.DrawImage(image, new PointF(0 + X, 0 + Y));
-
+ graphics.DrawImage(image, new PointF(0 + x, 0 + y));
}
+
return newImage;
}
+
+ ///
+ /// Returns the correct containing the angle for the given string.
+ ///
+ ///
+ /// The input string containing the value to parse.
+ ///
+ ///
+ /// The correct containing the angle for the given string.
+ ///
+ private int ParseAngle(string input)
+ {
+ foreach (Match match in AngleRegex.Matches(input))
+ {
+ // Split on angle-
+ int angle;
+ int.TryParse(match.Value.Replace("[", string.Empty).Replace("]", string.Empty).Split('-')[1], out angle);
+ return angle;
+ }
+
+ // No rotate - matches the RotateLayer default.
+ return 0;
+ }
+
+ ///
+ /// Returns the correct for the given string.
+ ///
+ ///
+ /// The input string containing the value to parse.
+ ///
+ ///
+ /// The correct
+ ///
+ 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;
+ }
+ #endregion
}
}
diff --git a/src/ImageProcessor/Processors/Watermark.cs b/src/ImageProcessor/Processors/Watermark.cs
index 147ee9fe9..8046545ee 100644
--- a/src/ImageProcessor/Processors/Watermark.cs
+++ b/src/ImageProcessor/Processors/Watermark.cs
@@ -452,7 +452,7 @@ namespace ImageProcessor.Processors
/// The input string containing the value to parse.
///
///
- /// The correct containing the font family for the given string.
+ /// The correct containing the opacity for the given string.
///
private int ParseOpacity(string input)
{
diff --git a/src/ImageProcessor/Properties/AssemblyInfo.cs b/src/ImageProcessor/Properties/AssemblyInfo.cs
index f783823f2..ecc917a5c 100644
--- a/src/ImageProcessor/Properties/AssemblyInfo.cs
+++ b/src/ImageProcessor/Properties/AssemblyInfo.cs
@@ -32,6 +32,6 @@ using System.Security;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.2.0")]
-[assembly: AssemblyFileVersion("1.0.2.0")]
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id b/src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id
new file mode 100644
index 000000000..9d6aad2d1
--- /dev/null
+++ b/src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id
@@ -0,0 +1 @@
+41192c06780bda40794dac2731a4105f1efe0311
\ No newline at end of file
diff --git a/src/Nuget/ImageProcessor.1.1.0.0.nupkg b/src/Nuget/ImageProcessor.1.1.0.0.nupkg
new file mode 100644
index 000000000..6113d379b
Binary files /dev/null and b/src/Nuget/ImageProcessor.1.1.0.0.nupkg differ
diff --git a/src/Nuget/ImageProcessor.Web.1.1.0.0.nupkg b/src/Nuget/ImageProcessor.Web.1.1.0.0.nupkg
new file mode 100644
index 000000000..e759b155a
Binary files /dev/null and b/src/Nuget/ImageProcessor.Web.1.1.0.0.nupkg differ
diff --git a/src/Test/Test/Test.csproj b/src/Test/Test/Test.csproj
index 45cf111ad..c629e6249 100644
--- a/src/Test/Test/Test.csproj
+++ b/src/Test/Test/Test.csproj
@@ -1,5 +1,6 @@
+
Debug
AnyCPU
@@ -15,6 +16,11 @@
v4.0
false
false
+
+
+
+
+ 4.0
true
@@ -149,8 +155,13 @@
+
+ 10.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
-
+
+