Browse Source

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: 0d811cd3c67b269183afc611bbf0f1ebd2f9750c
pull/17/head
perploug 12 years ago
parent
commit
32bc6e4bf4
  1. 6
      src/ImageProcessor/Imaging/ResizeLayer.cs
  2. 91
      src/ImageProcessor/Processors/Resize.cs

6
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.
/// </summary>
public bool Upscale { get; set; }
/// <summary>
/// Gets or sets the center coordinates.
/// </summary>
public float[] CenterCoordinates { get; set; }
#endregion
/// <summary>

91
src/ImageProcessor/Processors/Resize.cs

@ -34,7 +34,7 @@ namespace ImageProcessor.Processors
/// <summary>
/// The regular expression to search strings for.
/// </summary>
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);
/// <summary>
/// The regular expression to search strings for the size attribute.
@ -51,6 +51,11 @@ namespace ImageProcessor.Processors
/// </summary>
private static readonly Regex AnchorRegex = new Regex(@"anchor=(top|bottom|left|right|center)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the center attribute.
/// </summary>
private static readonly Regex CenterRegex = new Regex(@"center=\d+(.\d+)?[,-]\d+(.\d+)", RegexOptions.Compiled);
/// <summary>
/// The regular expression to search strings for the color attribute.
/// </summary>
@ -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<Size> 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
/// <param name="upscale">
/// Whether to allow up-scaling of images. (Default true)
/// </param>
/// <param name="center">
/// If resizemode is crop, you can set a specific center coordinate, use as alternative to anchorPosition
/// </param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
@ -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;
}
}
}

Loading…
Cancel
Save