diff --git a/README.md b/README.md
index 8db506628..7cc7e8bd4 100644
--- a/README.md
+++ b/README.md
@@ -121,11 +121,22 @@ Current filters include:
- gotham
- hisatch
- losatch
+ - invert
e.g.
+Flip
+=======
+
+Imageprocessor can flip your image either horizontally or vertically.
+
+e.g.
+
+
+
+
Watermark
=========
diff --git a/src/ImageProcessor.Tests/ImageProcessor.Tests.csproj b/src/ImageProcessor.Tests/ImageProcessor.Tests.csproj
index 00cf73739..c8d790034 100644
--- a/src/ImageProcessor.Tests/ImageProcessor.Tests.csproj
+++ b/src/ImageProcessor.Tests/ImageProcessor.Tests.csproj
@@ -53,7 +53,9 @@
MinimumRecommendedRules.ruleset
+
+
@@ -68,9 +70,19 @@
-
+
+
+
+ {4f7050f2-465f-4e10-8db2-2fb97ac6aa43}
+ ImageProcessor.Web
+
+
+ {3b5dd734-fb7a-487d-8ce6-55e7af9aea7e}
+ ImageProcessor
+
+
diff --git a/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs b/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs
new file mode 100644
index 000000000..c184374dd
--- /dev/null
+++ b/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs
@@ -0,0 +1,81 @@
+namespace ImageProcessor.Tests
+{
+ #region Using
+ using System;
+ using System.Diagnostics;
+ using System.Drawing;
+ using System.IO;
+ using System.Text.RegularExpressions;
+ using ImageProcessor.Imaging;
+ using ImageProcessor.Processors;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ #endregion
+
+ [TestClass]
+ public class RegularExpressionUnitTests
+ {
+ #region Regular Expression Tests
+ [TestMethod]
+ public void TestAlphaRegex()
+ {
+ string querystring = "alpha=56";
+ int expected = 56;
+
+ Alpha alpha = new Alpha();
+ alpha.MatchRegexIndex(querystring);
+
+ int actual = alpha.DynamicParameter;
+
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestFormatRegex()
+ {
+ string querystring = "format=gif";
+ string expected = "gif";
+
+ Format format = new Format();
+ format.MatchRegexIndex(querystring);
+
+ string actual = format.DynamicParameter;
+
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestQualityRegex()
+ {
+ string querystring = "quality=56";
+ int expected = 56;
+
+ Quality quality = new Quality();
+ quality.MatchRegexIndex(querystring);
+
+ int actual = quality.DynamicParameter;
+
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestRotateRegex()
+ {
+ string querystring = "rotate=270";
+ RotateLayer expected = new RotateLayer
+ {
+ Angle = 270,
+ BackgroundColor = Color.Transparent
+ };
+
+ Rotate rotate = new Rotate();
+ rotate.MatchRegexIndex(querystring);
+
+ RotateLayer actual = rotate.DynamicParameter;
+
+ Debug.Print("{0}{1}", actual.Angle, actual.BackgroundColor);
+
+ Assert.AreEqual(expected, actual);
+ }
+ #endregion
+ }
+}
diff --git a/src/ImageProcessor.Tests/UnitTest1.cs b/src/ImageProcessor.Tests/UnitTest1.cs
deleted file mode 100644
index f8dfa7ad7..000000000
--- a/src/ImageProcessor.Tests/UnitTest1.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace ImageProcessor.Tests
-{
- using System.IO;
-
- [TestClass]
- public class UnitTest1
- {
- [TestMethod]
- public void TestMethod1()
- {
-
-
- }
- }
-}
diff --git a/src/ImageProcessor.Web/Caching/SQLContext.cs b/src/ImageProcessor.Web/Caching/SQLContext.cs
index aef2bb4b7..05cd31aa1 100644
--- a/src/ImageProcessor.Web/Caching/SQLContext.cs
+++ b/src/ImageProcessor.Web/Caching/SQLContext.cs
@@ -29,7 +29,7 @@ namespace ImageProcessor.Web.Caching
///
/// The cached index location.
///
- private static readonly string IndexLocation = Path.Combine(HostingEnvironment.MapPath(VirtualCachePath), "imagecache.sqlite");
+ private static readonly string IndexLocation = Path.Combine(HostingEnvironment.MapPath(VirtualCachePath), "cache.db");
///
/// The connection string.
diff --git a/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs b/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
index 6a15c1677..dafa235ed 100644
--- a/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
+++ b/src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
@@ -85,6 +85,27 @@ namespace ImageProcessor.Helpers.Extensions
.ToString().ToLowerInvariant();
}
}
+
+ ///
+ /// Creates an SHA512 fingerprint of the String.
+ ///
+ /// The String instance that this method extends.
+ /// An SHA256 fingerprint of the String.
+ public static string ToSHA512Fingerprint(this string expression)
+ {
+ byte[] bytes = Encoding.ASCII.GetBytes(expression.ToCharArray());
+
+ using (SHA512CryptoServiceProvider sha512 = new SHA512CryptoServiceProvider())
+ {
+ byte[] hash = sha512.ComputeHash(bytes);
+
+ // Concatenate the hash bytes into one long String.
+ return hash.Aggregate(
+ new StringBuilder(70),
+ (sb, b) => sb.Append(b.ToString("X2", CultureInfo.InvariantCulture)))
+ .ToString().ToLowerInvariant();
+ }
+ }
#endregion
#region Numbers
diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs
index 6c0ec19ba..737b54778 100644
--- a/src/ImageProcessor/ImageFactory.cs
+++ b/src/ImageProcessor/ImageFactory.cs
@@ -254,6 +254,31 @@ namespace ImageProcessor
return this;
}
+ ///
+ /// Flips an image either horizontally or vertically.
+ ///
+ ///
+ /// Whether to flip the image vertically.
+ ///
+ ///
+ /// The current instance of the class.
+ ///
+ public ImageFactory Flip(bool flipVertically)
+ {
+ if (this.ShouldProcess)
+ {
+ RotateFlipType rotateFlipType = flipVertically == false
+ ? RotateFlipType.RotateNoneFlipX
+ : RotateFlipType.RotateNoneFlipY;
+
+ Flip flip = new Flip { DynamicParameter = rotateFlipType };
+
+ this.Image = flip.ProcessImage(this);
+ }
+
+ return this;
+ }
+
///
/// Sets the output format of the image to the matching .
///
diff --git a/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs
index 4b1d796b9..6fdd1f11d 100644
--- a/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs
@@ -41,7 +41,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
index 3523217a1..93394037e 100644
--- a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
@@ -65,7 +65,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
// Bitmaps for comic pattern
Bitmap hisatchBitmap = null;
diff --git a/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs
index 402777119..3f679d130 100644
--- a/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs
@@ -42,7 +42,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs
index 0a31f5137..46b64a379 100644
--- a/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs
@@ -41,7 +41,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs
index eddf5fc4d..1e6946f60 100644
--- a/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs
@@ -41,7 +41,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs
index 8036628ef..89783de41 100644
--- a/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs
@@ -35,7 +35,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- Image ProcessImage(ImageFactory factory, Image image, Image newImage);
+ Image TransformImage(ImageFactory factory, Image image, Image newImage);
#endregion
}
}
diff --git a/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs
index 5a886ca7f..dfd40b65f 100644
--- a/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs
@@ -41,7 +41,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs
index 8f87f0809..b02d19ad0 100644
--- a/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs
@@ -41,7 +41,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs
index 337968337..d9b92158f 100644
--- a/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs
@@ -42,7 +42,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs
index 25b53b235..60cd46ef7 100644
--- a/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs
@@ -43,7 +43,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs
index b9cfd65b0..6277a76a7 100644
--- a/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs
@@ -41,7 +41,7 @@ namespace ImageProcessor.Imaging.Filters
///
/// The processed image from the current instance of the class.
///
- public Image ProcessImage(ImageFactory factory, Image image, Image newImage)
+ public Image TransformImage(ImageFactory factory, Image image, Image newImage)
{
using (Graphics graphics = Graphics.FromImage(newImage))
{
diff --git a/src/ImageProcessor/Processors/Filter.cs b/src/ImageProcessor/Processors/Filter.cs
index 8efd88540..84103f9cf 100644
--- a/src/ImageProcessor/Processors/Filter.cs
+++ b/src/ImageProcessor/Processors/Filter.cs
@@ -178,7 +178,7 @@ namespace ImageProcessor.Processors
if (matrix != null)
{
- return matrix.ProcessImage(factory, image, newImage);
+ return matrix.TransformImage(factory, image, newImage);
}
}
catch
diff --git a/src/ImageProcessor/Processors/Flip.cs b/src/ImageProcessor/Processors/Flip.cs
index 9f528ac08..5b65b9452 100644
--- a/src/ImageProcessor/Processors/Flip.cs
+++ b/src/ImageProcessor/Processors/Flip.cs
@@ -109,7 +109,7 @@ namespace ImageProcessor.Processors
{
// Set the index on the first instance only.
this.SortOrder = match.Index;
- string direction = match.Value;
+ string direction = match.Value.Split('=')[1];
this.DynamicParameter = direction == "horizontal"
? RotateFlipType.RotateNoneFlipX
@@ -143,9 +143,10 @@ namespace ImageProcessor.Processors
RotateFlipType rotateFlipType = this.DynamicParameter;
newImage = (Bitmap)image.Clone();
-
- // Might not need this.
+ // Tag doesn't get cloned.
newImage.Tag = image.Tag;
+
+ // Flip
newImage.RotateFlip(rotateFlipType);
image.Dispose();
diff --git a/src/Test/Test/Controllers/HomeController.cs b/src/Test/Test/Controllers/HomeController.cs
index 9e859b0a6..818414c18 100644
--- a/src/Test/Test/Controllers/HomeController.cs
+++ b/src/Test/Test/Controllers/HomeController.cs
@@ -60,27 +60,29 @@ namespace Test.Controllers
DateTime start = DateTime.Now;
List collisions = new List();
-const int Iterations = 1;
-const int Maxitems = 360000;
+ const int Iterations = 1;
+ const int Maxitems = 360000;
-for (int i = 0; i < Iterations; i++)
-{
- List paths = new List();
+ for (int i = 0; i < Iterations; i++)
+ {
+ List paths = new List();
- for (int j = 0; j < Maxitems; j++)
- {
- string path = Path.GetRandomFileName().ToSHA256Fingerprint().Substring(0, 8);
+ for (int j = 0; j < Maxitems; j++)
+ {
+ string path = Path.GetRandomFileName().ToMD5Fingerprint();
- paths.Add(path);
- }
+ path = string.Format("{0}{1}", path.Substring(0, 4), path.Substring(16, 4));
- int count = paths.Distinct().Count();
+ paths.Add(path);
+ }
- double collisionRate = ((Maxitems - count) * 100D) / Maxitems;
- collisions.Add(collisionRate);
-}
+ int count = paths.Distinct().Count();
+
+ double collisionRate = ((Maxitems - count) * 100D) / Maxitems;
+ collisions.Add(collisionRate);
+ }
-double averageCollisionRate = collisions.Average();
+ double averageCollisionRate = collisions.Average();
//PersistantDictionary persistantDictionary = PersistantDictionary.Instance;
diff --git a/src/Test/Test/Images/negative.png b/src/Test/Test/Images/negative.png
new file mode 100644
index 000000000..a9de4cc09
--- /dev/null
+++ b/src/Test/Test/Images/negative.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:977cc9071257655c9923d267ea5bd417b69754367c2f1aa8765247b68e2bb878
+size 1539
diff --git a/src/Test/Test/Images/negative2.png.REMOVED.git-id b/src/Test/Test/Images/negative2.png.REMOVED.git-id
new file mode 100644
index 000000000..0f9ef2312
--- /dev/null
+++ b/src/Test/Test/Images/negative2.png.REMOVED.git-id
@@ -0,0 +1 @@
+ba8235d9051c4409559b4ec943172574041c0cf0
\ No newline at end of file
diff --git a/src/Test/Test/Views/Home/Index.cshtml b/src/Test/Test/Views/Home/Index.cshtml
index 05b7a8885..2c370f8a6 100644
--- a/src/Test/Test/Views/Home/Index.cshtml
+++ b/src/Test/Test/Views/Home/Index.cshtml
@@ -55,6 +55,14 @@
losatch
+
+ invert
+
+
+
+ invert
+
+
@@ -94,6 +102,18 @@
+
+
+
+
Flip - horizontal
+

+
+
+
Flip - vertical
+

+
+
+
Gif