From cc29d63d433516c6dcf2a98f79fe667e283a34a7 Mon Sep 17 00:00:00 2001 From: perploug Date: Wed, 19 Feb 2014 14:42:17 +0100 Subject: [PATCH 1/4] Enables setting a percentage-based center coordinate while resizing As an alternative to anchor points, this allows you to set a center=0.5,0.8 point, which in this case would be slightly off the center of the image. It allows you to translate image focal points to automated crops. Former-commit-id: f620b4b9858d0d12f9304f13db840fc716fdeb2b --- src/ImageProcessor/Imaging/ResizeLayer.cs | 6 ++ src/ImageProcessor/Processors/Resize.cs | 91 +++++++++++++++++------ 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/ImageProcessor/Imaging/ResizeLayer.cs b/src/ImageProcessor/Imaging/ResizeLayer.cs index 02c636b3d..4fe81645b 100644 --- a/src/ImageProcessor/Imaging/ResizeLayer.cs +++ b/src/ImageProcessor/Imaging/ResizeLayer.cs @@ -79,6 +79,12 @@ namespace ImageProcessor.Imaging /// Gets or sets a value indicating whether to allow up-scaling of images. /// public bool Upscale { get; set; } + + /// + /// Gets or sets the center coordinates. + /// + public float[] CenterCoordinates { get; set; } + #endregion /// diff --git a/src/ImageProcessor/Processors/Resize.cs b/src/ImageProcessor/Processors/Resize.cs index 018ebc76d..e4d6e7eae 100644 --- a/src/ImageProcessor/Processors/Resize.cs +++ b/src/ImageProcessor/Processors/Resize.cs @@ -34,7 +34,7 @@ namespace ImageProcessor.Processors /// /// The regular expression to search strings for. /// - private static readonly Regex QueryRegex = new Regex(@"((width|height)=\d+)|(mode=(pad|stretch|crop|max))|(anchor=(top|bottom|left|right|center))|(bgcolor=(transparent|\d+,\d+,\d+,\d+|([0-9a-fA-F]{3}){1,2}))|(upscale=false)", RegexOptions.Compiled); + private static readonly Regex QueryRegex = new Regex(@"((width|height)=\d+)|(mode=(pad|stretch|crop|max))|(anchor=(top|bottom|left|right|center))|(center=\d+(.\d+)?[,-]\d+(.\d+))|(bgcolor=(transparent|\d+,\d+,\d+,\d+|([0-9a-fA-F]{3}){1,2}))|(upscale=false)", RegexOptions.Compiled); /// /// The regular expression to search strings for the size attribute. @@ -51,6 +51,11 @@ namespace ImageProcessor.Processors /// private static readonly Regex AnchorRegex = new Regex(@"anchor=(top|bottom|left|right|center)", RegexOptions.Compiled); + /// + /// The regular expression to search strings for the center attribute. + /// + private static readonly Regex CenterRegex = new Regex(@"center=\d+(.\d+)?[,-]\d+(.\d+)", RegexOptions.Compiled); + /// /// The regular expression to search strings for the color attribute. /// @@ -144,10 +149,12 @@ namespace ImageProcessor.Processors ResizeMode = this.ParseMode(toParse), AnchorPosition = this.ParsePosition(toParse), BackgroundColor = this.ParseColor(toParse), - Upscale = !UpscaleRegex.IsMatch(toParse) + Upscale = !UpscaleRegex.IsMatch(toParse), }; + resizeLayer.CenterCoordinates= this.ParseCoordinates(toParse); this.DynamicParameter = resizeLayer; + return this.SortOrder; } @@ -169,6 +176,7 @@ namespace ImageProcessor.Processors AnchorPosition anchor = this.DynamicParameter.AnchorPosition; Color backgroundColor = this.DynamicParameter.BackgroundColor; bool upscale = this.DynamicParameter.Upscale; + float[] centerCoordinates = this.DynamicParameter.CenterCoordinates; int defaultMaxWidth; int defaultMaxHeight; @@ -178,7 +186,8 @@ namespace ImageProcessor.Processors int.TryParse(this.Settings["MaxHeight"], out defaultMaxHeight); List restrictedSizes = this.ParseRestrictions(restrictions); - return this.ResizeImage(factory, width, height, defaultMaxWidth, defaultMaxHeight, restrictedSizes, backgroundColor, mode, anchor, upscale); + + return this.ResizeImage(factory, width, height, defaultMaxWidth, defaultMaxHeight, restrictedSizes, backgroundColor, mode, anchor, upscale, centerCoordinates); } #endregion @@ -216,6 +225,9 @@ namespace ImageProcessor.Processors /// /// Whether to allow up-scaling of images. (Default true) /// + /// + /// If resizemode is crop, you can set a specific center coordinate, use as alternative to anchorPosition + /// /// /// The processed image from the current instance of the class. /// @@ -229,7 +241,8 @@ namespace ImageProcessor.Processors Color backgroundColor, ResizeMode resizeMode = ResizeMode.Pad, AnchorPosition anchorPosition = AnchorPosition.Center, - bool upscale = true) + bool upscale = true, + float[] centerCoordinates = null) { Bitmap newImage = null; Image image = factory.Image; @@ -244,7 +257,7 @@ namespace ImageProcessor.Processors int maxWidth = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue; int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue; - + // Fractional variants for preserving aspect ratio. double percentHeight = Math.Abs(height / (double)sourceHeight); double percentWidth = Math.Abs(width / (double)sourceWidth); @@ -282,17 +295,29 @@ namespace ImageProcessor.Processors { ratio = percentWidth; - switch (anchorPosition) + if (centerCoordinates.Any()) { - case AnchorPosition.Top: + destinationY = (int)((centerCoordinates[0] * sourceHeight) * ratio) - (height / 2); + if (destinationY < 0) destinationY = 0; - break; - case AnchorPosition.Bottom: + + if (destinationY + height > (sourceHeight * ratio)) destinationY = (int)(height - (sourceHeight * ratio)); - break; - default: - destinationY = (int)((height - (sourceHeight * ratio)) / 2); - break; + } + else + { + switch (anchorPosition) + { + case AnchorPosition.Top: + destinationY = 0; + break; + case AnchorPosition.Bottom: + destinationY = (int)(height - (sourceHeight * ratio)); + break; + default: + destinationY = (int)((height - (sourceHeight * ratio)) / 2); + break; + } } destinationHeight = (int)Math.Ceiling(sourceHeight * percentWidth); @@ -301,17 +326,29 @@ namespace ImageProcessor.Processors { ratio = percentHeight; - switch (anchorPosition) + if (centerCoordinates.Any()) { - case AnchorPosition.Left: + destinationX = (int)((centerCoordinates[1] * sourceWidth) * ratio) - (width / 2); + if (destinationX < 0) destinationX = 0; - break; - case AnchorPosition.Right: + + if (destinationX + width > (sourceWidth * ratio)) destinationX = (int)(width - (sourceWidth * ratio)); - break; - default: - destinationX = (int)((width - (sourceWidth * ratio)) / 2); - break; + } + else + { + switch (anchorPosition) + { + case AnchorPosition.Left: + destinationX = 0; + break; + case AnchorPosition.Right: + destinationX = (int)(width - (sourceWidth * ratio)); + break; + default: + destinationX = (int)((width - (sourceWidth * ratio)) / 2); + break; + } } destinationWidth = (int)Math.Ceiling(sourceWidth * percentHeight); @@ -602,5 +639,17 @@ namespace ImageProcessor.Processors return sizes; } + + private float[] ParseCoordinates(string input) + { + float[] floats = { }; + + foreach (Match match in CenterRegex.Matches(input)) + { + floats = match.Value.ToPositiveFloatArray(); + } + + return floats; + } } } From df5c95cdb81d1ed50bae15fc17b006825e600727 Mon Sep 17 00:00:00 2001 From: perploug Date: Thu, 20 Feb 2014 08:35:47 +0100 Subject: [PATCH 2/4] Tweaking the center calculation abit Former-commit-id: 1c29005edce7d8ddf809c1a11cc491beaf90e7eb --- src/ImageProcessor/Processors/Resize.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ImageProcessor/Processors/Resize.cs b/src/ImageProcessor/Processors/Resize.cs index e4d6e7eae..577c9bb2e 100644 --- a/src/ImageProcessor/Processors/Resize.cs +++ b/src/ImageProcessor/Processors/Resize.cs @@ -297,11 +297,13 @@ namespace ImageProcessor.Processors if (centerCoordinates.Any()) { - destinationY = (int)((centerCoordinates[0] * sourceHeight) * ratio) - (height / 2); - if (destinationY < 0) + var center = -(ratio * sourceHeight) * centerCoordinates[0]; + destinationY = (int)center + (height / 2); + + if (destinationY > 0) destinationY = 0; - if (destinationY + height > (sourceHeight * ratio)) + if (destinationY < (int)(height - (sourceHeight * ratio))) destinationY = (int)(height - (sourceHeight * ratio)); } else @@ -328,11 +330,13 @@ namespace ImageProcessor.Processors if (centerCoordinates.Any()) { - destinationX = (int)((centerCoordinates[1] * sourceWidth) * ratio) - (width / 2); - if (destinationX < 0) + var center = -(ratio * sourceWidth) * centerCoordinates[1]; + destinationX = (int)center + (width / 2); + + if (destinationX > 0) destinationX = 0; - if (destinationX + width > (sourceWidth * ratio)) + if (destinationX < (int)(width - (sourceWidth * ratio))) destinationX = (int)(width - (sourceWidth * ratio)); } else From 8263907f86d2acd4ff7180a868a7047672470e71 Mon Sep 17 00:00:00 2001 From: James South Date: Mon, 24 Feb 2014 14:20:34 +0000 Subject: [PATCH 3/4] Fixes #31 Former-commit-id: d2470b5e658916b6e3850604e6049275fe1d2696 --- src/ImageProcessor/Processors/Resize.cs | 38 ++++++++++++++----- .../config/imageprocessor/processing.config | 4 +- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/ImageProcessor/Processors/Resize.cs b/src/ImageProcessor/Processors/Resize.cs index 577c9bb2e..94b0bcef4 100644 --- a/src/ImageProcessor/Processors/Resize.cs +++ b/src/ImageProcessor/Processors/Resize.cs @@ -152,7 +152,7 @@ namespace ImageProcessor.Processors Upscale = !UpscaleRegex.IsMatch(toParse), }; - resizeLayer.CenterCoordinates= this.ParseCoordinates(toParse); + resizeLayer.CenterCoordinates = this.ParseCoordinates(toParse); this.DynamicParameter = resizeLayer; return this.SortOrder; @@ -225,8 +225,8 @@ namespace ImageProcessor.Processors /// /// Whether to allow up-scaling of images. (Default true) /// - /// - /// If resizemode is crop, you can set a specific center coordinate, use as alternative to anchorPosition + /// + /// If the resize mode is crop, you can set a specific center coordinate, use as alternative to anchorPosition /// /// /// The processed image from the current instance of the class. @@ -257,7 +257,7 @@ namespace ImageProcessor.Processors int maxWidth = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue; int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue; - + // Fractional variants for preserving aspect ratio. double percentHeight = Math.Abs(height / (double)sourceHeight); double percentWidth = Math.Abs(width / (double)sourceWidth); @@ -295,16 +295,20 @@ namespace ImageProcessor.Processors { ratio = percentWidth; - if (centerCoordinates.Any()) + if (centerCoordinates != null && centerCoordinates.Any()) { - var center = -(ratio * sourceHeight) * centerCoordinates[0]; + double center = -(ratio * sourceHeight) * centerCoordinates[0]; destinationY = (int)center + (height / 2); if (destinationY > 0) + { destinationY = 0; + } if (destinationY < (int)(height - (sourceHeight * ratio))) + { destinationY = (int)(height - (sourceHeight * ratio)); + } } else { @@ -328,16 +332,20 @@ namespace ImageProcessor.Processors { ratio = percentHeight; - if (centerCoordinates.Any()) + if (centerCoordinates != null && centerCoordinates.Any()) { - var center = -(ratio * sourceWidth) * centerCoordinates[1]; + double center = -(ratio * sourceWidth) * centerCoordinates[1]; destinationX = (int)center + (width / 2); if (destinationX > 0) + { destinationX = 0; + } if (destinationX < (int)(width - (sourceWidth * ratio))) + { destinationX = (int)(width - (sourceWidth * ratio)); + } } else { @@ -397,7 +405,14 @@ namespace ImageProcessor.Processors bool reject = true; foreach (Size restrictedSize in restrictedSizes) { - if (restrictedSize.Width == width && restrictedSize.Height == height) + if (restrictedSize.Height == 0 || restrictedSize.Width == 0) + { + if (restrictedSize.Width == width || restrictedSize.Height == height) + { + reject = false; + } + } + else if (restrictedSize.Width == width && restrictedSize.Height == height) { reject = false; } @@ -644,6 +659,11 @@ namespace ImageProcessor.Processors return sizes; } + /// + /// Parses the coordinates. + /// + /// The input. + /// The array containing the coordinates private float[] ParseCoordinates(string input) { float[] floats = { }; diff --git a/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/processing.config b/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/processing.config index 654a9fbd6..98d50805f 100644 --- a/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/processing.config +++ b/src/TestWebsites/NET45/Test_Website_NET45/config/imageprocessor/processing.config @@ -1,7 +1,7 @@  - + @@ -30,7 +30,7 @@ - + From 5fbaf243b24d574f9d588329dca126580201d022 Mon Sep 17 00:00:00 2001 From: James South Date: Tue, 4 Mar 2014 13:45:43 +0000 Subject: [PATCH 4/4] v1.8.4 Former-commit-id: 37033a655ed08272087c2929b33e88d75ca3ecf0 --- src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs | 4 ++-- src/ImageProcessor/Properties/AssemblyInfo.cs | 4 ++-- src/Nuget/ImageProcessor.1.8.4.0.nupkg.REMOVED.git-id | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 src/Nuget/ImageProcessor.1.8.4.0.nupkg.REMOVED.git-id diff --git a/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs b/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs index eb681c5e4..71a8792cf 100644 --- a/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ 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("3.1.1.0")] -[assembly: AssemblyFileVersion("3.1.1.0")] +[assembly: AssemblyVersion("3.1.2.0")] +[assembly: AssemblyFileVersion("3.1.2.0")] diff --git a/src/ImageProcessor/Properties/AssemblyInfo.cs b/src/ImageProcessor/Properties/AssemblyInfo.cs index 53d7fac06..9d8014b36 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.8.3.0")] -[assembly: AssemblyFileVersion("1.8.3.0")] +[assembly: AssemblyVersion("1.8.4.0")] +[assembly: AssemblyFileVersion("1.8.4.0")] diff --git a/src/Nuget/ImageProcessor.1.8.4.0.nupkg.REMOVED.git-id b/src/Nuget/ImageProcessor.1.8.4.0.nupkg.REMOVED.git-id new file mode 100644 index 000000000..902c55ada --- /dev/null +++ b/src/Nuget/ImageProcessor.1.8.4.0.nupkg.REMOVED.git-id @@ -0,0 +1 @@ +effc95273383a6d336dd589cf684b3952cb98699 \ No newline at end of file