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..94b0bcef4 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 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.
///
@@ -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;
@@ -282,17 +295,35 @@ namespace ImageProcessor.Processors
{
ratio = percentWidth;
- switch (anchorPosition)
+ if (centerCoordinates != null && centerCoordinates.Any())
{
- case AnchorPosition.Top:
+ double center = -(ratio * sourceHeight) * centerCoordinates[0];
+ destinationY = (int)center + (height / 2);
+
+ if (destinationY > 0)
+ {
destinationY = 0;
- break;
- case AnchorPosition.Bottom:
+ }
+
+ if (destinationY < (int)(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 +332,35 @@ namespace ImageProcessor.Processors
{
ratio = percentHeight;
- switch (anchorPosition)
+ if (centerCoordinates != null && centerCoordinates.Any())
{
- case AnchorPosition.Left:
+ double center = -(ratio * sourceWidth) * centerCoordinates[1];
+ destinationX = (int)center + (width / 2);
+
+ if (destinationX > 0)
+ {
destinationX = 0;
- break;
- case AnchorPosition.Right:
+ }
+
+ if (destinationX < (int)(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);
@@ -356,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;
}
@@ -602,5 +658,22 @@ namespace ImageProcessor.Processors
return sizes;
}
+
+ ///
+ /// Parses the coordinates.
+ ///
+ /// The input.
+ /// The array containing the coordinates
+ private float[] ParseCoordinates(string input)
+ {
+ float[] floats = { };
+
+ foreach (Match match in CenterRegex.Matches(input))
+ {
+ floats = match.Value.ToPositiveFloatArray();
+ }
+
+ return floats;
+ }
}
}
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
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 @@
-
+