diff --git a/src/ImageProcessor.Playground/Program.cs b/src/ImageProcessor.Playground/Program.cs
index b04275ff10..6e509e4e08 100644
--- a/src/ImageProcessor.Playground/Program.cs
+++ b/src/ImageProcessor.Playground/Program.cs
@@ -79,7 +79,7 @@ namespace ImageProcessor.PlayGround
//.Resize(new Size((int)(size.Width * 1.1), 0))
//.ContentAwareResize(layer)
.Constrain(size)
- .Mask(mask)
+ //.Mask(mask)
//.Format(new PngFormat())
//.BackgroundColor(Color.HotPink)
//.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80)
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index 9d0a96b57c..dbbbffe881 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -193,6 +193,7 @@
+
@@ -209,6 +210,7 @@
+
diff --git a/src/ImageProcessor/Imaging/ResizeLayer.cs b/src/ImageProcessor/Imaging/ResizeLayer.cs
index d4c114b1ee..36176090c9 100644
--- a/src/ImageProcessor/Imaging/ResizeLayer.cs
+++ b/src/ImageProcessor/Imaging/ResizeLayer.cs
@@ -11,6 +11,8 @@
namespace ImageProcessor.Imaging
{
#region Using
+
+ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -41,18 +43,30 @@ namespace ImageProcessor.Imaging
///
/// The center coordinates (Default null)
///
+ ///
+ /// The maximum size to resize an image to.
+ /// Used to restrict resizing based on calculated resizing
+ ///
+ ///
+ /// The range of sizes to restrict resizing an image to.
+ /// Used to restrict resizing based on calculated resizing
+ ///
public ResizeLayer(
Size size,
ResizeMode resizeMode = ResizeMode.Pad,
AnchorPosition anchorPosition = AnchorPosition.Center,
bool upscale = true,
- float[] centerCoordinates = null)
+ float[] centerCoordinates = null,
+ Size? maxSize = null,
+ List restrictedSizes = null)
{
this.Size = size;
this.Upscale = upscale;
this.ResizeMode = resizeMode;
this.AnchorPosition = anchorPosition;
this.CenterCoordinates = centerCoordinates ?? new float[] { };
+ this.MaxSize = maxSize;
+ this.RestrictedSizes = restrictedSizes ?? new List();
}
#endregion
@@ -62,6 +76,16 @@ namespace ImageProcessor.Imaging
///
public Size Size { get; set; }
+ ///
+ /// Gets or sets the max size.
+ ///
+ public Size? MaxSize { get; set; }
+
+ ///
+ /// Gets or sets the restricted range of sizes. to restrict resizing methods to.
+ ///
+ public List RestrictedSizes { get; set; }
+
///
/// Gets or sets the resize mode.
///
@@ -81,7 +105,6 @@ namespace ImageProcessor.Imaging
/// Gets or sets the center coordinates.
///
public float[] CenterCoordinates { get; set; }
-
#endregion
///
@@ -109,7 +132,9 @@ namespace ImageProcessor.Imaging
&& this.ResizeMode == resizeLayer.ResizeMode
&& this.AnchorPosition == resizeLayer.AnchorPosition
&& this.Upscale == resizeLayer.Upscale
- && this.CenterCoordinates.SequenceEqual(resizeLayer.CenterCoordinates);
+ && this.CenterCoordinates.SequenceEqual(resizeLayer.CenterCoordinates)
+ && this.MaxSize == resizeLayer.MaxSize
+ && this.RestrictedSizes.SequenceEqual(resizeLayer.RestrictedSizes);
}
///
@@ -123,6 +148,8 @@ namespace ImageProcessor.Imaging
unchecked
{
int hashCode = this.Size.GetHashCode();
+ hashCode = (hashCode * 397) ^ this.MaxSize.GetHashCode();
+ hashCode = (hashCode * 397) ^ (this.RestrictedSizes != null ? this.RestrictedSizes.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (int)this.ResizeMode;
hashCode = (hashCode * 397) ^ (int)this.AnchorPosition;
hashCode = (hashCode * 397) ^ this.Upscale.GetHashCode();
diff --git a/src/ImageProcessor/Imaging/Resizer.cs b/src/ImageProcessor/Imaging/Resizer.cs
new file mode 100644
index 0000000000..ed774ceea0
--- /dev/null
+++ b/src/ImageProcessor/Imaging/Resizer.cs
@@ -0,0 +1,365 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Provides methods to resize images.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Imaging
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Drawing;
+ using System.Drawing.Drawing2D;
+ using System.Drawing.Imaging;
+ using System.Linq;
+
+ using ImageProcessor.Common.Exceptions;
+
+ ///
+ /// Provides methods to resize images.
+ ///
+ public class Resizer
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The to resize the image to.
+ ///
+ public Resizer(Size size)
+ {
+ this.ResizeLayer = new ResizeLayer(size);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The .
+ ///
+ public Resizer(ResizeLayer resizeLayer)
+ {
+ this.ResizeLayer = resizeLayer;
+ }
+
+ ///
+ /// Gets or sets the .
+ ///
+ public ResizeLayer ResizeLayer { get; set; }
+
+ ///
+ /// Resizes the given image.
+ ///
+ ///
+ /// The source to resize
+ ///
+ ///
+ /// The resized .
+ ///
+ public Image ResizeImage(Image source)
+ {
+ int width = this.ResizeLayer.Size.Width;
+ int height = this.ResizeLayer.Size.Height;
+ ResizeMode mode = this.ResizeLayer.ResizeMode;
+ AnchorPosition anchor = this.ResizeLayer.AnchorPosition;
+ bool upscale = this.ResizeLayer.Upscale;
+ float[] centerCoordinates = this.ResizeLayer.CenterCoordinates;
+ int maxWidth = this.ResizeLayer.MaxSize.HasValue ? this.ResizeLayer.MaxSize.Value.Width : int.MaxValue;
+ int maxHeight = this.ResizeLayer.MaxSize.HasValue ? this.ResizeLayer.MaxSize.Value.Height : int.MaxValue;
+ List restrictedSizes = this.ResizeLayer.RestrictedSizes;
+
+ return this.ResizeImage(source, width, height, maxWidth, maxHeight, restrictedSizes, mode, anchor, upscale, centerCoordinates);
+ }
+
+ ///
+ /// Resizes the given image.
+ ///
+ ///
+ /// The source to resize
+ ///
+ ///
+ /// The width to resize the image to.
+ ///
+ ///
+ /// The height to resize the image to.
+ ///
+ ///
+ /// The default max width to resize the image to.
+ ///
+ ///
+ /// The default max height to resize the image to.
+ ///
+ ///
+ /// A containing image resizing restrictions.
+ ///
+ ///
+ /// The mode with which to resize the image.
+ ///
+ ///
+ /// The anchor position to place the image at.
+ ///
+ ///
+ /// 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 resized .
+ ///
+ private Image ResizeImage(
+ Image source,
+ int width,
+ int height,
+ int maxWidth,
+ int maxHeight,
+ List restrictedSizes,
+ ResizeMode resizeMode = ResizeMode.Pad,
+ AnchorPosition anchorPosition = AnchorPosition.Center,
+ bool upscale = true,
+ float[] centerCoordinates = null)
+ {
+ Bitmap newImage = null;
+
+ try
+ {
+ int sourceWidth = source.Width;
+ int sourceHeight = source.Height;
+
+ int destinationWidth = width;
+ int destinationHeight = height;
+
+ maxWidth = maxWidth > 0 ? maxWidth : int.MaxValue;
+ maxHeight = maxHeight > 0 ? maxHeight : int.MaxValue;
+
+ // Fractional variants for preserving aspect ratio.
+ double percentHeight = Math.Abs(height / (double)sourceHeight);
+ double percentWidth = Math.Abs(width / (double)sourceWidth);
+
+ int destinationX = 0;
+ int destinationY = 0;
+
+ // Change the destination rectangle coordinates if padding and
+ // there has been a set width and height.
+ if (resizeMode == ResizeMode.Pad && width > 0 && height > 0)
+ {
+ double ratio;
+
+ if (percentHeight < percentWidth)
+ {
+ ratio = percentHeight;
+ destinationX = Convert.ToInt32((width - (sourceWidth * ratio)) / 2);
+ destinationWidth = Convert.ToInt32(sourceWidth * percentHeight);
+ }
+ else
+ {
+ ratio = percentWidth;
+ destinationY = Convert.ToInt32((height - (sourceHeight * ratio)) / 2);
+ destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
+ }
+ }
+
+ // Change the destination rectangle coordinates if cropping and
+ // there has been a set width and height.
+ if (resizeMode == ResizeMode.Crop && width > 0 && height > 0)
+ {
+ double ratio;
+
+ if (percentHeight < percentWidth)
+ {
+ ratio = percentWidth;
+
+ if (centerCoordinates != null && centerCoordinates.Any())
+ {
+ 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
+ {
+ 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);
+ }
+ else
+ {
+ ratio = percentHeight;
+
+ if (centerCoordinates != null && centerCoordinates.Any())
+ {
+ 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
+ {
+ 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);
+ }
+ }
+
+ // Constrain the image to fit the maximum possible height or width.
+ if (resizeMode == ResizeMode.Max)
+ {
+ // If either is 0, we don't need to figure out orientation
+ if (width > 0 && height > 0)
+ {
+ // Integers must be cast to doubles to get needed precision
+ double ratio = (double)height / width;
+ double sourceRatio = (double)sourceHeight / sourceWidth;
+
+ if (sourceRatio < ratio)
+ {
+ height = 0;
+ }
+ else
+ {
+ width = 0;
+ }
+ }
+ }
+
+ // If height or width is not passed we assume that the standard ratio is to be kept.
+ if (height == 0)
+ {
+ destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
+ height = destinationHeight;
+ }
+
+ if (width == 0)
+ {
+ destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
+ width = destinationWidth;
+ }
+
+ // Restrict sizes
+ if (restrictedSizes != null && restrictedSizes.Any())
+ {
+ bool reject = true;
+ foreach (Size restrictedSize in restrictedSizes)
+ {
+ 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;
+ }
+ }
+
+ if (reject)
+ {
+ return source;
+ }
+ }
+
+ if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight)
+ {
+ // Exit if upscaling is not allowed.
+ if ((width > sourceWidth || height > sourceHeight) && upscale == false && resizeMode != ResizeMode.Stretch)
+ {
+ return source;
+ }
+
+ newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
+
+ using (Graphics graphics = Graphics.FromImage(newImage))
+ {
+ // We want to use two different blending algorithms for enlargement/shrinking.
+ if (source.Width < destinationWidth && source.Height < destinationHeight)
+ {
+ // We are making it larger.
+ graphics.SmoothingMode = SmoothingMode.AntiAlias;
+ }
+ else
+ {
+ // We are making it smaller.
+ graphics.SmoothingMode = SmoothingMode.None;
+ }
+
+ graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
+ graphics.CompositingQuality = CompositingQuality.HighQuality;
+
+ // An unwanted border appears when using InterpolationMode.HighQualityBicubic to resize the image
+ // as the algorithm appears to be pulling averaging detail from surrounding pixels beyond the edge
+ // of the image. Using the ImageAttributes class to specify that the pixels beyond are simply mirror
+ // images of the pixels within solves this problem.
+ using (ImageAttributes wrapMode = new ImageAttributes())
+ {
+ wrapMode.SetWrapMode(WrapMode.TileFlipXY);
+ Rectangle destRect = new Rectangle(destinationX, destinationY, destinationWidth, destinationHeight);
+ graphics.DrawImage(source, destRect, 0, 0, sourceWidth, sourceHeight, GraphicsUnit.Pixel, wrapMode);
+ }
+
+ // Reassign the image.
+ source.Dispose();
+ source = newImage;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (newImage != null)
+ {
+ newImage.Dispose();
+ }
+
+ throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
+ }
+
+ return source;
+ }
+ }
+}
diff --git a/src/ImageProcessor/Processors/Overlay.cs b/src/ImageProcessor/Processors/Overlay.cs
new file mode 100644
index 0000000000..ff4579bd70
--- /dev/null
+++ b/src/ImageProcessor/Processors/Overlay.cs
@@ -0,0 +1,63 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Adds an image overlay to the current image.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Processors
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Drawing;
+
+ ///
+ /// Adds an image overlay to the current image.
+ ///
+ public class Overlay : IGraphicsProcessor
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Overlay()
+ {
+ this.Settings = new Dictionary();
+ }
+
+ ///
+ /// Gets or sets the dynamic parameter.
+ ///
+ public dynamic DynamicParameter
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets any additional settings required by the processor.
+ ///
+ public Dictionary Settings
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Processes the image.
+ ///
+ ///
+ /// The current instance of the class containing
+ /// the image to process.
+ ///
+ ///
+ /// The processed image from the current instance of the class.
+ ///
+ public Image ProcessImage(ImageFactory factory)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/ImageProcessor/Processors/Resize.cs b/src/ImageProcessor/Processors/Resize.cs
index 34f598eadf..b2e0bc80cf 100644
--- a/src/ImageProcessor/Processors/Resize.cs
+++ b/src/ImageProcessor/Processors/Resize.cs
@@ -13,10 +13,7 @@ namespace ImageProcessor.Processors
using System;
using System.Collections.Generic;
using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
using System.Globalization;
- using System.Linq;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging;
@@ -31,6 +28,7 @@ namespace ImageProcessor.Processors
///
public Resize()
{
+ this.RestrictedSizes = new List();
this.Settings = new Dictionary();
}
@@ -68,298 +66,34 @@ namespace ImageProcessor.Processors
/// The processed image from the current instance of the class.
///
public Image ProcessImage(ImageFactory factory)
- {
- int width = this.DynamicParameter.Size.Width ?? 0;
- int height = this.DynamicParameter.Size.Height ?? 0;
- ResizeMode mode = this.DynamicParameter.ResizeMode;
- AnchorPosition anchor = this.DynamicParameter.AnchorPosition;
- bool upscale = this.DynamicParameter.Upscale;
- float[] centerCoordinates = this.DynamicParameter.CenterCoordinates;
-
- int defaultMaxWidth;
- int defaultMaxHeight;
-
- int.TryParse(this.Settings["MaxWidth"], NumberStyles.Any, CultureInfo.InvariantCulture, out defaultMaxWidth);
- int.TryParse(this.Settings["MaxHeight"], NumberStyles.Any, CultureInfo.InvariantCulture, out defaultMaxHeight);
-
- return this.ResizeImage(factory, width, height, defaultMaxWidth, defaultMaxHeight, this.RestrictedSizes, mode, anchor, upscale, centerCoordinates);
- }
-
- ///
- /// The resize image.
- ///
- ///
- /// The current instance of the class containing
- /// the image to process.
- ///
- ///
- /// The width to resize the image to.
- ///
- ///
- /// The height to resize the image to.
- ///
- ///
- /// The default max width to resize the image to.
- ///
- ///
- /// The default max height to resize the image to.
- ///
- ///
- /// A containing image resizing restrictions.
- ///
- ///
- /// The mode with which to resize the image.
- ///
- ///
- /// The anchor position to place the image at.
- ///
- ///
- /// 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.
- ///
- private Image ResizeImage(
- ImageFactory factory,
- int width,
- int height,
- int defaultMaxWidth,
- int defaultMaxHeight,
- List restrictedSizes,
- ResizeMode resizeMode = ResizeMode.Pad,
- AnchorPosition anchorPosition = AnchorPosition.Center,
- bool upscale = true,
- float[] centerCoordinates = null)
{
Bitmap newImage = null;
Image image = factory.Image;
try
{
- int sourceWidth = image.Width;
- int sourceHeight = image.Height;
+ ResizeLayer resizeLayer = this.DynamicParameter;
+
+ // Augment the layer with the extra information.
+ resizeLayer.RestrictedSizes = this.RestrictedSizes;
+ Size maxSize = new Size();
- int destinationWidth = width;
- int destinationHeight = height;
+ int maxWidth;
+ int maxHeight;
+ int.TryParse(this.Settings["MaxWidth"], NumberStyles.Any, CultureInfo.InvariantCulture, out maxWidth);
+ int.TryParse(this.Settings["MaxHeight"], NumberStyles.Any, CultureInfo.InvariantCulture, out maxHeight);
- int maxWidth = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue;
- int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue;
+ maxSize.Width = maxHeight;
+ maxSize.Height = maxHeight;
- // Fractional variants for preserving aspect ratio.
- double percentHeight = Math.Abs(height / (double)sourceHeight);
- double percentWidth = Math.Abs(width / (double)sourceWidth);
-
- int destinationX = 0;
- int destinationY = 0;
-
- // Change the destination rectangle coordinates if padding and
- // there has been a set width and height.
- if (resizeMode == ResizeMode.Pad && width > 0 && height > 0)
- {
- double ratio;
-
- if (percentHeight < percentWidth)
- {
- ratio = percentHeight;
- destinationX = Convert.ToInt32((width - (sourceWidth * ratio)) / 2);
- destinationWidth = Convert.ToInt32(sourceWidth * percentHeight);
- }
- else
- {
- ratio = percentWidth;
- destinationY = Convert.ToInt32((height - (sourceHeight * ratio)) / 2);
- destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
- }
- }
-
- // Change the destination rectangle coordinates if cropping and
- // there has been a set width and height.
- if (resizeMode == ResizeMode.Crop && width > 0 && height > 0)
- {
- double ratio;
+ resizeLayer.MaxSize = maxSize;
- if (percentHeight < percentWidth)
- {
- ratio = percentWidth;
+ Resizer resizer = new Resizer(resizeLayer);
+ newImage = (Bitmap)resizer.ResizeImage(image);
- if (centerCoordinates != null && centerCoordinates.Any())
- {
- 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
- {
- 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);
- }
- else
- {
- ratio = percentHeight;
-
- if (centerCoordinates != null && centerCoordinates.Any())
- {
- 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
- {
- 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);
- }
- }
-
- // Constrain the image to fit the maximum possible height or width.
- if (resizeMode == ResizeMode.Max)
- {
- // If either is 0, we don't need to figure out orientation
- if (width > 0 && height > 0)
- {
- // Integers must be cast to doubles to get needed precision
- double ratio = (double)height / width;
- double sourceRatio = (double)sourceHeight / sourceWidth;
-
- if (sourceRatio < ratio)
- {
- height = 0;
- }
- else
- {
- width = 0;
- }
- }
- }
-
- // If height or width is not passed we assume that the standard ratio is to be kept.
- if (height == 0)
- {
- destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
- height = destinationHeight;
- }
-
- if (width == 0)
- {
- destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
- width = destinationWidth;
- }
-
- // Restrict sizes
- if (restrictedSizes != null && restrictedSizes.Any())
- {
- bool reject = true;
- foreach (Size restrictedSize in restrictedSizes)
- {
- 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;
- }
- }
-
- if (reject)
- {
- return image;
- }
- }
-
- if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight)
- {
- // Exit if upscaling is not allowed.
- if ((width > sourceWidth || height > sourceHeight) && upscale == false && resizeMode != ResizeMode.Stretch)
- {
- return image;
- }
-
- newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
-
- using (Graphics graphics = Graphics.FromImage(newImage))
- {
- // We want to use two different blending algorithms for enlargement/shrinking.
- if (image.Width < destinationWidth && image.Height < destinationHeight)
- {
- // We are making it larger.
- graphics.SmoothingMode = SmoothingMode.AntiAlias;
- }
- else
- {
- // We are making it smaller.
- graphics.SmoothingMode = SmoothingMode.None;
- }
-
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
-
- // An unwanted border appears when using InterpolationMode.HighQualityBicubic to resize the image
- // as the algorithm appears to be pulling averaging detail from surrounding pixels beyond the edge
- // of the image. Using the ImageAttributes class to specify that the pixels beyond are simply mirror
- // images of the pixels within solves this problem.
- using (ImageAttributes wrapMode = new ImageAttributes())
- {
- wrapMode.SetWrapMode(WrapMode.TileFlipXY);
- Rectangle destRect = new Rectangle(destinationX, destinationY, destinationWidth, destinationHeight);
- graphics.DrawImage(image, destRect, 0, 0, sourceWidth, sourceHeight, GraphicsUnit.Pixel, wrapMode);
- }
-
- // Reassign the image.
- image.Dispose();
- image = newImage;
- }
- }
+ // Reassign the image.
+ image.Dispose();
+ image = newImage;
}
catch (Exception ex)
{