diff --git a/src/ImageProcessor.Web/Configuration/Resources/processing.config b/src/ImageProcessor.Web/Configuration/Resources/processing.config index bbb28f6e8..11c2fcfbf 100644 --- a/src/ImageProcessor.Web/Configuration/Resources/processing.config +++ b/src/ImageProcessor.Web/Configuration/Resources/processing.config @@ -7,8 +7,9 @@ - + + diff --git a/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs b/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs index 3e8362d08..273f478ef 100644 --- a/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs +++ b/src/ImageProcessor.Web/Helpers/CommonParameterParserUtility.cs @@ -35,7 +35,7 @@ namespace ImageProcessor.Web.Helpers /// The regular expression to search strings for colors. /// private static readonly Regex ColorRegex = BuildColorRegex(); - + /// /// The regular expression to search strings for angles. /// diff --git a/src/ImageProcessor.Web/ImageProcessor.Web.csproj b/src/ImageProcessor.Web/ImageProcessor.Web.csproj index e98b1ad50..f19d4a04d 100644 --- a/src/ImageProcessor.Web/ImageProcessor.Web.csproj +++ b/src/ImageProcessor.Web/ImageProcessor.Web.csproj @@ -47,6 +47,7 @@ + diff --git a/src/ImageProcessor.Web/Processors/Crop.cs b/src/ImageProcessor.Web/Processors/Crop.cs index c669c8e1b..35c7b47c3 100644 --- a/src/ImageProcessor.Web/Processors/Crop.cs +++ b/src/ImageProcessor.Web/Processors/Crop.cs @@ -86,7 +86,8 @@ namespace ImageProcessor.Web.Processors foreach (Match match in this.RegexPattern.Matches(queryString)) { - if (match.Success) + // Match but ignore entropy + if (match.Success && !queryString.ToUpperInvariant().Contains("ENTROPYCROP=")) { if (index == 0) { diff --git a/src/ImageProcessor.Web/Processors/EntropyCrop.cs b/src/ImageProcessor.Web/Processors/EntropyCrop.cs new file mode 100644 index 000000000..ac1cafb0c --- /dev/null +++ b/src/ImageProcessor.Web/Processors/EntropyCrop.cs @@ -0,0 +1,119 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// Performs a crop on an image to the area of greatest entropy. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Web.Processors +{ + using System.Globalization; + using System.Text.RegularExpressions; + + using ImageProcessor.Common.Extensions; + using ImageProcessor.Processors; + + /// + /// Performs a crop on an image to the area of greatest entropy. + /// + public class EntropyCrop : IWebGraphicsProcessor + { + /// + /// The regular expression to search strings for. + /// + private static readonly Regex QueryRegex = new Regex(@"entropycrop=(\d+)[^&]+|entropycrop", RegexOptions.Compiled); + + /// + /// Initializes a new instance of the class. + /// + public EntropyCrop() + { + this.Processor = new ImageProcessor.Processors.EntropyCrop(); + } + + /// + /// Gets the regular expression to search strings for. + /// + public Regex RegexPattern + { + get + { + return QueryRegex; + } + } + + /// + /// Gets the order in which this processor is to be used in a chain. + /// + public int SortOrder { get; private set; } + + /// + /// Gets the associated graphics processor. + /// + public IGraphicsProcessor Processor { get; private set; } + + /// + /// The position in the original string where the first character of the captured substring was found. + /// + /// The query string to search. + /// + /// The zero-based starting position in the original string where the captured substring was found. + /// + 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; + byte threshold = this.ParseThreshold(match.Value); + this.Processor.DynamicParameter = threshold; + } + + index += 1; + } + } + + return this.SortOrder; + } + + /// + /// Returns the correct containing the radius for the given string. + /// + /// + /// The input string containing the value to parse. + /// + /// + /// The correct containing the radius for the given string. + /// + private byte ParseThreshold(string input) + { + foreach (Match match in QueryRegex.Matches(input)) + { + if (!match.Value.Contains("=")) + { + continue; + } + + // Split on threshold + int threshold; + int.TryParse(match.Value.Split('=')[1], NumberStyles.Any, CultureInfo.InvariantCulture, out threshold); + return threshold.ToByte(); + } + + // No threshold - matches the EntropyCrop default. + return 128; + } + } +} diff --git a/src/TestWebsites/MVC/config/imageprocessor/processing.config b/src/TestWebsites/MVC/config/imageprocessor/processing.config index 33c9a5c65..a2f931462 100644 --- a/src/TestWebsites/MVC/config/imageprocessor/processing.config +++ b/src/TestWebsites/MVC/config/imageprocessor/processing.config @@ -9,6 +9,7 @@ +