From 13931014e95ce877c9fb7a1bf41eb2b09bcb8705 Mon Sep 17 00:00:00 2001 From: James South Date: Thu, 28 Feb 2013 15:33:22 +0000 Subject: [PATCH] V1.3.0 Fixed concurrency bug Fixed Rotate regex bug Changed the Resize method to accept a System.Drawing.Size Changed the Rotate method to accept an ImageProcessor.Imaging.RotateLayer Reoganized project. Former-commit-id: 0dc963f74c9f8a7c1967ca328fa70a9e4ad40a0f --- README.md | 64 ++++-- .../HttpModules/ImageProcessingModule.cs | 35 ++- .../ImageFactoryExtensions.cs | 42 ++-- .../ImageProcessor.Web.vsdoc | 96 --------- .../Properties/AssemblyInfo.cs | 6 +- src/{ImageProcessor => }/ImageProcessor.sln | 8 +- src/ImageProcessor/ImageFactory.cs | 5 +- src/ImageProcessor/ImageProcessor.sln.vsdoc | 7 - src/ImageProcessor/ImageProcessor.vsdoc | 105 --------- src/ImageProcessor/Processors/Rotate.cs | 2 +- src/ImageProcessor/Properties/AssemblyInfo.cs | 6 +- .../UpgradeLog.htm.REMOVED.git-id | 1 - src/Test/Test.sln | 20 -- src/Test/Test/Content/style.css | 22 +- src/Test/Test/Test.csproj | 3 - src/Test/Test/Views/Home/Index.cshtml | 137 +++++++----- src/Test/Test/Views/Shared/_Layout.cshtml | 19 +- src/Test/Test/Web.config | 204 ++++++++---------- src/Test/Test/packages.config | 4 - 19 files changed, 297 insertions(+), 489 deletions(-) delete mode 100644 src/ImageProcessor.Web/ImageProcessor.Web.vsdoc rename src/{ImageProcessor => }/ImageProcessor.sln (85%) delete mode 100644 src/ImageProcessor/ImageProcessor.sln.vsdoc delete mode 100644 src/ImageProcessor/ImageProcessor.vsdoc delete mode 100644 src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id delete mode 100644 src/Test/Test.sln delete mode 100644 src/Test/Test/packages.config diff --git a/README.md b/README.md index 9dc295163..8db506628 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,21 @@ ImageProcessor =============== -ImageProcessor is a library for on the fly processing of image files using Asp.Net 4 written in c#. +Imageprocessor is a lightweight library written in C# that allows you to manipulate images on-the-fly using ASP.NET 4.0. -The library architecture is highly extensible and allows for easy extension. +It's fast, extensible, easy to use, comes bundled with some great features and is fully open source. Core plugins at present include: - Resize - Crop - - Quality (The quality to set the output for jpeg files) - - Filter (Image filters including sepia, greyscale, blackwhite, lomograph, comic) - - Vignette (Adds a vignette effect to images) - - Format (Sets the output format) - Alpha (Sets opacity) + - Filter (Image filters including sepia, greyscale, blackwhite, lomograph, polaroid, comic, gotham, hisatch, losatch) - Watermark (Set a text watermark) + - Format (Sets the output format) + - Rotate (Rotate the image) + - Quality (The quality to set the output for jpeg files) + - Vignette (Adds a vignette effect to images) The library consists of two binaries: **ImageProcessor.dll** and **ImageProcessor.Web.dll**. @@ -24,9 +25,9 @@ e.g. // Read a file and resize it. byte[] photoBytes = File.ReadAllBytes(file); - int quality = 90; + int quality = 70; ImageFormat format = ImageFormat.Jpeg; - int thumbnailSize = 150; + Size size = new Size(150, 0) using (var inStream = new MemoryStream(photoBytes)) { @@ -34,9 +35,15 @@ e.g. { using (ImageFactory imageFactory = new ImageFactory()) { - // Load, resize and save an image. - imageFactory.Load(inStream).Format(format).Quality(quality).Resize(thumbnailSize, 0).Save(outStream); + // Load, resize, set the format and quality and save an image. + imageFactory.Load(inStream) + .Resize(size) + .Format(format) + .Quality(quality) + .Save(outStream); } + + // Do something with the stream. } } @@ -44,14 +51,18 @@ e.g. Using the HttpModule requires no code writing at all. Just reference the binaries and add the relevant sections to the web.config -Image requests suffixed with QueryString parameters will then be processed and cached to the server allowing for easy and efficient parsing of following requests. +Image requests suffixed with querystring parameters will then be processed and cached to the server allowing for easy and efficient parsing of following requests. The parsing engine for the HttpModule is incredibly flexible and will **allow you to add querystring parameters in any order.** Installation ============ -Installation is simple. Download the zip file from the downloads section and copy the two binaries into your bin folder. Then copy the example configuration values from the `config.txt` into your `web.config` to enable the processor. A Nuget package will be created once I've read the manual to allow simpler installation in the future. +Installation is simple. A Nuget package is available [here][1]. + + [1]: http://nuget.org/packages/ImageProcessor/ + +Alternatively you can download and build the project and reference the binaries. Then copy the example configuration values from the demo project into your `web.config` to enable the processor. Usage ===== @@ -144,10 +155,37 @@ Supported file format just now are: - jpg - bmp - png - - gif + - gif (requires full trust) e.g. your image as a gif +Rotate +====== + +Imageprocessor can rotate your images without clipping. You can also optionally fill the background color for image types without transparency. + +e.g. + + your image rotated + your image rotated + +Quality +====== + +Whilst Imageprocessor delivers an excellent quality/filesize ratio it also allows you to change the quality of jpegs on-the-fly. + +e.g. + + your image at quality 30 + +Vignette +====== + +Imageprocessor can also add a vignette effect to images. + +e.g. + + your image vignetted diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs index ccd1a7325..f28724d3a 100644 --- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs @@ -123,40 +123,35 @@ namespace ImageProcessor.Web.HttpModules } // Process the image. - if (isRemote) + using (ImageFactory imageFactory = new ImageFactory()) { - Uri uri = new Uri(path); - RemoteFile remoteFile = new RemoteFile(uri, false); - - using (MemoryStream memoryStream = new MemoryStream()) + if (isRemote) { - using (Stream responseStream = remoteFile.GetWebResponse().GetResponseStream()) + Uri uri = new Uri(path); + RemoteFile remoteFile = new RemoteFile(uri, false); + + using (MemoryStream memoryStream = new MemoryStream()) { - if (responseStream != null) + using (Stream responseStream = remoteFile.GetWebResponse().GetResponseStream()) { - responseStream.CopyTo(memoryStream); - // Process the image. - using (ImageFactory imageFactory = new ImageFactory()) + if (responseStream != null) { + responseStream.CopyTo(memoryStream); + imageFactory.Load(memoryStream) - .AddQueryString(queryString) - .Format(ImageUtils.GetImageFormat(imageName)) - .AutoProcess() - .Save(cachedPath); + .AddQueryString(queryString) + .Format(ImageUtils.GetImageFormat(imageName)) + .AutoProcess().Save(cachedPath); } } } } - } - else - { - using (ImageFactory imageFactory = new ImageFactory()) + else { imageFactory.Load(fullPath).AutoProcess().Save(cachedPath); } } - // Add 1 to the counter cachedImageCounter += 1; @@ -255,4 +250,4 @@ namespace ImageProcessor.Web.HttpModules } #endregion } -} +} \ No newline at end of file diff --git a/src/ImageProcessor.Web/ImageFactoryExtensions.cs b/src/ImageProcessor.Web/ImageFactoryExtensions.cs index d22b8282a..23eaa1eb7 100644 --- a/src/ImageProcessor.Web/ImageFactoryExtensions.cs +++ b/src/ImageProcessor.Web/ImageFactoryExtensions.cs @@ -24,6 +24,8 @@ namespace ImageProcessor.Web /// public static class ImageFactoryExtensions { + private static readonly object SyncLock = new object(); + /// /// Auto processes image files based on any querystring parameters added to the image path. /// @@ -38,42 +40,26 @@ namespace ImageProcessor.Web { if (factory.ShouldProcess) { - // Get a list of all graphics processors that have parsed and matched the querystring. - List list = - ImageProcessorConfig.Instance.GraphicsProcessors - .Where(x => x.MatchRegexIndex(factory.QueryString) != int.MaxValue) - .OrderBy(y => y.SortOrder) - .ToList(); - - // Loop through and process the image. - foreach (IGraphicsProcessor graphicsProcessor in list) + // TODO: This is going to be a bottleneck for speed. Find a faster way. + lock (SyncLock) { - try - { - // TODO: This is going to be a bottleneck for speed. Find a faster way. - IGraphicsProcessor processor = - (IGraphicsProcessor)Activator.CreateInstance(graphicsProcessor.GetType()); - // Get the dynamic parameter. - processor.MatchRegexIndex(factory.QueryString); - // Process. - factory.Image = processor.ProcessImage(factory); + // Get a list of all graphics processors that have parsed and matched the querystring. + List list = + ImageProcessorConfig.Instance.GraphicsProcessors + .Where(x => x.MatchRegexIndex(factory.QueryString) != int.MaxValue) + .OrderBy(y => y.SortOrder) + .ToList(); - //// TODO: This is going to be a bottleneck for speed. Find a faster way. - //IGraphicsProcessor processor = - // (IGraphicsProcessor)Activator.CreateInstance(graphicsProcessor.GetType()); - //// Get the dynamic parameter. - //processor.MatchRegexIndex(factory.QueryString); - //// Process. - //factory.Image = processor.ProcessImage(factory); - } - catch (Exception ex) + // Loop through and process the image. + foreach (IGraphicsProcessor graphicsProcessor in list) { - throw ex; + factory.Image = graphicsProcessor.ProcessImage(factory); } } } return factory; + } diff --git a/src/ImageProcessor.Web/ImageProcessor.Web.vsdoc b/src/ImageProcessor.Web/ImageProcessor.Web.vsdoc deleted file mode 100644 index 26a18eb4c..000000000 --- a/src/ImageProcessor.Web/ImageProcessor.Web.vsdoc +++ /dev/null @@ -1,96 +0,0 @@ - - - - default - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - normal - yes - ImageProcessor.Web Reference - imageprocessorweb_reference - vsdocman_escaped_]_]_> - - - - placeholder - no - - d85a6fde0cd5454f9dc418dda28f5422 - - - - - - -]]> - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/ImageProcessor.Web/Properties/AssemblyInfo.cs b/src/ImageProcessor.Web/Properties/AssemblyInfo.cs index 3ecc7da4c..89e023946 100644 --- a/src/ImageProcessor.Web/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor.Web/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("James South")] [assembly: AssemblyCompany("James South")] [assembly: AssemblyProduct("ImageProcessor.Web")] -[assembly: AssemblyCopyright("Copyright ©")] +[assembly: AssemblyCopyright("Copyright © James South")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -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.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] diff --git a/src/ImageProcessor/ImageProcessor.sln b/src/ImageProcessor.sln similarity index 85% rename from src/ImageProcessor/ImageProcessor.sln rename to src/ImageProcessor.sln index a6b3bf630..39c5c7a26 100644 --- a/src/ImageProcessor/ImageProcessor.sln +++ b/src/ImageProcessor.sln @@ -1,11 +1,11 @@  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}" +# Visual Studio Express 2012 for Web +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor", "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}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test\Test.csproj", "{30327C08-7574-4D7E-AC95-6A58753C6855}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web", "..\ImageProcessor.Web\ImageProcessor.Web.csproj", "{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web", "ImageProcessor.Web\ImageProcessor.Web.csproj", "{4F7050F2-465F-4E10-8DB2-2FB97AC6AA43}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index 96f5e0fe4..6c0ec19ba 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -318,7 +318,7 @@ namespace ImageProcessor /// Rotates the current image by the given angle. /// /// - /// The RotateLayer containing the properties to rotate the image. + /// The containing the properties to rotate the image. /// /// /// The current instance of the class. @@ -363,7 +363,8 @@ namespace ImageProcessor /// Adds a text based watermark to the image /// /// - /// The text layer containing the properties necessary to add the text based watermark to the image. + /// The containing the properties necessary to add + /// the text based watermark to the image. /// /// /// The current instance of the class. diff --git a/src/ImageProcessor/ImageProcessor.sln.vsdoc b/src/ImageProcessor/ImageProcessor.sln.vsdoc deleted file mode 100644 index 9ffff5e7f..000000000 --- a/src/ImageProcessor/ImageProcessor.sln.vsdoc +++ /dev/null @@ -1,7 +0,0 @@ - - - - default - - - diff --git a/src/ImageProcessor/ImageProcessor.vsdoc b/src/ImageProcessor/ImageProcessor.vsdoc deleted file mode 100644 index 1607ec517..000000000 --- a/src/ImageProcessor/ImageProcessor.vsdoc +++ /dev/null @@ -1,105 +0,0 @@ - - - - default - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - normal - yes - ImageProcessor Reference - imageprocessor_reference - vsdocman_escaped_]_]_> - - - - placeholder - no - - e3cba20ec62e422b8bb39e6be7ca2142 - - - - - - -]]> - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/ImageProcessor/Processors/Rotate.cs b/src/ImageProcessor/Processors/Rotate.cs index 4b5bb3290..35bb7b110 100644 --- a/src/ImageProcessor/Processors/Rotate.cs +++ b/src/ImageProcessor/Processors/Rotate.cs @@ -24,7 +24,7 @@ namespace ImageProcessor.Processors /// /// The regular expression to search strings for. /// - private static readonly Regex QueryRegex = new Regex(@"rotate=((?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)|angle-(?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)\|bgcolor=([0-9a-fA-F]{3}){1,2})", RegexOptions.Compiled); + private static readonly Regex QueryRegex = new Regex(@"rotate=((?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)|angle-(?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)\|bgcolor-([0-9a-fA-F]{3}){1,2})", RegexOptions.Compiled); /// /// The regular expression to search strings for the angle attribute. diff --git a/src/ImageProcessor/Properties/AssemblyInfo.cs b/src/ImageProcessor/Properties/AssemblyInfo.cs index 07501a11f..23e407cbc 100644 --- a/src/ImageProcessor/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor/Properties/AssemblyInfo.cs @@ -11,7 +11,7 @@ using System.Security; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("James South")] [assembly: AssemblyProduct("ImageProcessor")] -[assembly: AssemblyCopyright("Copyright ©")] +[assembly: AssemblyCopyright("Copyright © James South")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -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.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] diff --git a/src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id b/src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id deleted file mode 100644 index 9d6aad2d1..000000000 --- a/src/ImageProcessor/UpgradeLog.htm.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -41192c06780bda40794dac2731a4105f1efe0311 \ No newline at end of file diff --git a/src/Test/Test.sln b/src/Test/Test.sln deleted file mode 100644 index 7893f8741..000000000 --- a/src/Test/Test.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{30327C08-7574-4D7E-AC95-6A58753C6855}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {30327C08-7574-4D7E-AC95-6A58753C6855}.Debug|Any CPU.Build.0 = Debug|Any CPU - {30327C08-7574-4D7E-AC95-6A58753C6855}.Release|Any CPU.ActiveCfg = Release|Any CPU - {30327C08-7574-4D7E-AC95-6A58753C6855}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/Test/Test/Content/style.css b/src/Test/Test/Content/style.css index dfafde877..6848b86e7 100644 --- a/src/Test/Test/Content/style.css +++ b/src/Test/Test/Content/style.css @@ -13,11 +13,29 @@ h1 { font-size: 3em; } +section section { + padding-bottom: 1em; + margin-bottom: 2em; +} + + section section:nth-child(2n) { + color: #fff; + } + + + section section:nth-child(2) { + background-color: #00a9ec; + } + + section section:nth-child(4) { + background-color: #ED1C24; + } + img { - background: #fff; + /*background: #fff; padding: 3px; -webkit-box-shadow: 0 0 5px rgb(0, 0, 0, 0.4); - box-shadow: 0 0 5px rgb(0, 0, 0, 0.4); + box-shadow: 0 0 5px rgb(0, 0, 0, 0.4);*/ } .no-bullets { diff --git a/src/Test/Test/Test.csproj b/src/Test/Test/Test.csproj index dcb138427..89dfe6596 100644 --- a/src/Test/Test/Test.csproj +++ b/src/Test/Test/Test.csproj @@ -117,9 +117,6 @@ - - - {4F7050F2-465F-4E10-8DB2-2FB97AC6AA43} diff --git a/src/Test/Test/Views/Home/Index.cshtml b/src/Test/Test/Views/Home/Index.cshtml index 47d9dae31..981fb6aaf 100644 --- a/src/Test/Test/Views/Home/Index.cshtml +++ b/src/Test/Test/Views/Home/Index.cshtml @@ -1,57 +1,94 @@ @{ ViewBag.Title = "Home Page"; } -
-@*
-

Resized Image

- +
+
+
+

Resized

+ +
+
+

Cropped

+ +
+
+
+
+
+

Filter

+
    +
  • +

    blackwhite

    + +
  • +
  • +

    comic

    + +
  • +
  • +

    lomograph

    + +
  • +
  • +

    greyscale

    + +
  • +
  • +

    polaroid

    + +
  • +
  • +

    sepia

    + +
  • +
  • +

    gotham

    + +
  • +
  • +

    hisatch

    + +
  • +
  • +

    losatch

    + +
  • +
-
-

Cropped Image

- -
*@
-

Filtered Image

-
    -
  • -

    blackwhite

    - -
  • -
  • -

    comic

    - -
  • -
  • -

    lomograph

    - -
  • -@*
  • -

    greyscale

    - -
  • -
  • -

    polaroid

    - -
  • -
  • -

    sepia

    - -
  • -
  • -

    gotham

    - -
  • -
  • -

    hisatch

    - -
  • -
  • -

    losatch

    - -
  • *@ -
- +
+
+

Watermark

+ +
+
+

Format

+ +
+
+
+
+
+
+

Rotate

+ +
+
+

Quality

+ +
+
+
+
+
+
+

Alpha

+ +
+
+

Remote

+ +
+
-@*

Remote image test

-*@ \ No newline at end of file diff --git a/src/Test/Test/Views/Shared/_Layout.cshtml b/src/Test/Test/Views/Shared/_Layout.cshtml index 09632c130..3e05d2770 100644 --- a/src/Test/Test/Views/Shared/_Layout.cshtml +++ b/src/Test/Test/Views/Shared/_Layout.cshtml @@ -8,17 +8,16 @@
-
-
-
-

ImageProcessor Test Website

-
-
-
- @RenderBody() -
-
+
+
+

ImageProcessor Test Website

+
+
+
+ @RenderBody() +
+
diff --git a/src/Test/Test/Web.config b/src/Test/Test/Web.config index 0f037fa20..d13d11155 100644 --- a/src/Test/Test/Web.config +++ b/src/Test/Test/Web.config @@ -1,117 +1,87 @@ - - - - - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Test/Test/packages.config b/src/Test/Test/packages.config deleted file mode 100644 index dde88d7f2..000000000 --- a/src/Test/Test/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file