Browse Source

Fixing bad merge

Former-commit-id: 3a5876081417adfb614040f1eba3b2f09cc20ad8
pull/17/head
James South 13 years ago
parent
commit
07d135a0fa
  1. 56
      src/ImageProcessor.Tests/RegularExpressionUnitTests.cs
  2. 32
      src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
  3. 32
      src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
  4. 4
      src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs
  5. 11
      src/ImageProcessor/Helpers/Extensions/StringExtensions.cs
  6. 36
      src/ImageProcessor/ImageFactory.cs
  7. 2
      src/ImageProcessor/ImageProcessor.csproj
  8. 15
      src/ImageProcessor/Imaging/ImageUtils.cs
  9. 136
      src/ImageProcessor/Processors/Constrain.cs
  10. 2
      src/ImageProcessor/Processors/Crop.cs
  11. 126
      src/ImageProcessor/Processors/Resize.cs
  12. 179
      src/ImageProcessor/Processors/ResizeBase.cs
  13. 4
      src/ImageProcessor/Properties/AssemblyInfo.cs
  14. BIN
      src/Nuget/ImageProcessor.1.7.0.0.nupkg
  15. BIN
      src/Nuget/ImageProcessor.1.7.0.1.nupkg
  16. BIN
      src/Nuget/ImageProcessor.1.7.0.2.nupkg
  17. BIN
      src/Nuget/ImageProcessor.1.7.0.3.nupkg
  18. BIN
      src/Nuget/ImageProcessor.1.7.1.1.nupkg
  19. 1
      src/Nuget/ImageProcessor.Web.2.3.0.3.nupkg.REMOVED.git-id
  20. 1
      src/Nuget/ImageProcessor.Web.2.3.0.4.nupkg.REMOVED.git-id
  21. 1
      src/Nuget/ImageProcessor.Web.2.3.0.5.nupkg.REMOVED.git-id
  22. 1
      src/Nuget/ImageProcessor.Web.2.3.0.6.nupkg.REMOVED.git-id
  23. 6
      src/TestWebsites/NET4/Web.config
  24. 4
      src/TestWebsites/NET45/Test_Website_NET45/Test_Website_NET45.csproj
  25. 134
      src/TestWebsites/NET45/Test_Website_NET45/Web.config

56
src/ImageProcessor.Tests/RegularExpressionUnitTests.cs

@ -56,24 +56,44 @@ namespace ImageProcessor.Tests
Assert.AreEqual(Expected, actual);
}
/// <summary>
/// The contrast regex unit test.
/// </summary>
[TestMethod]
public void TestContrastRegex()
{
const string Querystring = "contrast=56";
const int Expected = 56;
Contrast contrast = new Contrast();
contrast.MatchRegexIndex(Querystring);
int actual = contrast.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
/// <summary>
/// <summary>
/// The contrast regex unit test.
/// </summary>
[TestMethod]
public void TestContrastRegex()
{
const string Querystring = "contrast=56";
const int Expected = 56;
Contrast contrast = new Contrast();
contrast.MatchRegexIndex(Querystring);
int actual = contrast.DynamicParameter;
Assert.AreEqual(Expected, actual);
}
/// <summary>
/// The constrain regex unit test.
/// </summary>
[TestMethod]
public void TestConstrainRegex()
{
const string Querystring = "constrain=100,200";
const int ExpectedWidth = 100;
const int ExpectedHeight = 200;
Constrain contrast = new Constrain();
contrast.MatchRegexIndex(Querystring);
int actualWidth = contrast.DynamicParameter.Width;
int actualHeight = contrast.DynamicParameter.Height;
Assert.AreEqual(ExpectedWidth, actualWidth);
Assert.AreEqual(ExpectedHeight, actualHeight);
}
/// <summary>
/// The rotate regex unit test.
/// </summary>
[TestMethod]

32
src/ImageProcessor.Web/NET45/Caching/DiskCache.cs

@ -306,6 +306,18 @@ namespace ImageProcessor.Web.Caching
return isUpdated;
}
/// <summary>
/// Gets the <see cref="T:System.DateTime"/> set to the last write time of the file.
/// </summary>
/// <returns>
/// The last write time of the file.
/// </returns>
internal async Task<DateTime> GetLastWriteTimeAsync()
{
// Create Action delegate for TrimCachedFolders.
return await TaskHelpers.Run<DateTime>(this.GetLastWriteTime);
}
/// <summary>
/// Sets the LastWriteTime of the cached file to match the original file.
/// </summary>
@ -448,6 +460,26 @@ namespace ImageProcessor.Web.Caching
return cachedPath;
}
/// <summary>
/// Gets last modified time of the image.
/// </summary>
/// <returns>
/// The <see cref="DateTime"/> representing the last modified time of the image.
/// </returns>
private DateTime GetLastWriteTime()
{
string key = Path.GetFileNameWithoutExtension(this.CachedPath);
CachedImage cachedImage;
DateTime dateTime = DateTime.UtcNow;
if (PersistantDictionary.Instance.TryGetValue(key, out cachedImage))
{
dateTime = cachedImage.LastWriteTimeUtc;
}
return dateTime;
}
/// <summary>
/// The rough date time compare.
/// </summary>

32
src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs

@ -304,6 +304,23 @@ namespace ImageProcessor.Web.HttpModules
// Store the response type in the context for later retrieval.
context.Items[CachedResponseTypeKey] = ImageUtils.GetResponseType(fullPath).ToDescription();
string incomingEtag = context.Request.Headers["If-None-Match"];
if (incomingEtag != null && !isNewOrUpdated)
{
// Explicitly set the Content-Length header so the client doesn't wait for
// content but keeps the connection open for other requests
context.Response.AddHeader("Content-Length", "0");
context.Response.StatusCode = (int)HttpStatusCode.NotModified;
context.Response.SuppressContent = true;
this.SetHeaders(context, (string)context.Items[CachedResponseTypeKey]);
if (!isRemote)
{
return;
}
}
// The cached file is valid so just rewrite the path.
context.RewritePath(cache.GetVirtualCachedPath(), false);
@ -334,7 +351,7 @@ namespace ImageProcessor.Web.HttpModules
response.AddHeader("Image-Served-By", "ImageProcessor.Web/" + AssemblyVersion);
HttpCachePolicy cache = response.Cache;
cache.SetCacheability(HttpCacheability.Public);
cache.VaryByHeaders["Accept-Encoding"] = true;
int maxDays = DiskCache.MaxFileCachedDuration;
@ -342,19 +359,6 @@ namespace ImageProcessor.Web.HttpModules
cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(maxDays));
cache.SetMaxAge(new TimeSpan(maxDays, 0, 0, 0));
cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
string incomingEtag = context.Request.Headers["If-None-Match"];
cache.SetCacheability(HttpCacheability.Public);
if (incomingEtag == null)
{
return;
}
response.Clear();
response.StatusCode = (int)HttpStatusCode.NotModified;
response.SuppressContent = true;
}
#endregion
}

4
src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs

@ -31,5 +31,5 @@ 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("2.3.0.4")]
[assembly: AssemblyFileVersion("2.3.0.4")]
[assembly: AssemblyVersion("2.3.0.6")]
[assembly: AssemblyFileVersion("2.3.0.6")]

11
src/ImageProcessor/Helpers/Extensions/StringExtensions.cs

@ -1,9 +1,12 @@
// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="StringExtensions.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// -----------------------------------------------------------------------
// <summary>
// Encapsulates a series of time saving extension methods to the <see cref="T:System.String" /> class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Helpers.Extensions
{

36
src/ImageProcessor/ImageFactory.cs

@ -38,6 +38,11 @@ namespace ImageProcessor
/// </summary>
private ImageFormat backupImageFormat;
/// <summary>
/// The original extension.
/// </summary>
private string originalExtension;
/// <summary>
/// Whether the image is indexed.
/// </summary>
@ -184,6 +189,7 @@ namespace ImageProcessor
this.JpegQuality = DefaultJpegQuality;
ImageFormat imageFormat = ImageUtils.GetImageFormat(imageName);
this.backupImageFormat = imageFormat;
this.originalExtension = Path.GetExtension(this.ImagePath);
this.ImageFormat = imageFormat;
this.isIndexed = ImageUtils.IsIndexed(this.Image);
this.ShouldProcess = true;
@ -315,6 +321,32 @@ namespace ImageProcessor
return this;
}
/// <summary>
/// Constrains the current image, resizing it to fit within the given dimensions whilst keeping its aspect ratio.
/// </summary>
/// <param name="size">
/// The <see cref="T:System.Drawing.Size"/> containing the maximum width and height to set the image to.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public ImageFactory Constrain(Size size)
{
if (this.ShouldProcess)
{
int width = size.Width;
int height = size.Height;
var constrainSettings = new Dictionary<string, string> { { "MaxWidth", width.ToString("G") }, { "MaxHeight", height.ToString("G") } };
Constrain constrain = new Constrain { DynamicParameter = new Size(width, height), Settings = constrainSettings };
this.Image = constrain.ProcessImage(this);
}
return this;
}
/// <summary>
/// Changes the contrast of the current image.
/// </summary>
@ -343,6 +375,8 @@ namespace ImageProcessor
return this;
}
/// <summary>
/// Crops the current image to the given location and size.
/// </summary>
@ -612,7 +646,7 @@ namespace ImageProcessor
// We need to check here if the path has an extension and remove it if so.
// This is so we can add the correct image format.
int length = filePath.LastIndexOf(".", StringComparison.Ordinal);
string extension = ImageUtils.GetExtensionFromImageFormat(this.ImageFormat);
string extension = ImageUtils.GetExtensionFromImageFormat(this.ImageFormat, this.originalExtension);
filePath = length == -1 ? filePath + extension : filePath.Substring(0, length) + extension;
// Fix the colour palette of indexed images.

2
src/ImageProcessor/ImageProcessor.csproj

@ -81,7 +81,9 @@
<Compile Include="Imaging\TextLayer.cs" />
<Compile Include="Processors\Alpha.cs" />
<Compile Include="Processors\Brightness.cs" />
<Compile Include="Processors\Constrain.cs" />
<Compile Include="Processors\Contrast.cs" />
<Compile Include="Processors\ResizeBase.cs" />
<Compile Include="Processors\RoundedCorners.cs" />
<Compile Include="Processors\Saturate.cs" />
<Compile Include="Processors\Flip.cs" />

15
src/ImageProcessor/Imaging/ImageUtils.cs

@ -102,10 +102,13 @@ namespace ImageProcessor.Imaging
/// <param name="imageFormat">
/// The <see cref="T:System.Drawing.Imaging.ImageFormat"/> to return the extension for.
/// </param>
/// <param name="originalExtension">
/// The original Extension.
/// </param>
/// <returns>
/// The correct file extension for the given <see cref="T:System.Drawing.Imaging.ImageFormat"/>.
/// </returns>
public static string GetExtensionFromImageFormat(ImageFormat imageFormat)
public static string GetExtensionFromImageFormat(ImageFormat imageFormat, string originalExtension)
{
switch (imageFormat.ToString())
{
@ -117,8 +120,18 @@ namespace ImageProcessor.Imaging
return ".png";
case "Tif":
case "Tiff":
if (!string.IsNullOrWhiteSpace(originalExtension) && originalExtension.ToUpperInvariant() == ".TIFF")
{
return ".tiff";
}
return ".tif";
default:
if (!string.IsNullOrWhiteSpace(originalExtension) && originalExtension.ToUpperInvariant() == ".JPEG")
{
return ".jpeg";
}
return ".jpg";
}
}

136
src/ImageProcessor/Processors/Constrain.cs

@ -0,0 +1,136 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Constrain.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Constrains an image to the given dimensions.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{
#region Using
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using ImageProcessor.Helpers.Extensions;
#endregion
/// <summary>
/// Constrains an image to the given dimensions.
/// </summary>
public class Constrain : ResizeBase
{
/// <summary>
/// The regular expression to search strings for.
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"constrain=\d+[,-]\d+", RegexOptions.Compiled);
#region IGraphicsProcessor Members
/// <summary>
/// Gets the regular expression to search strings for.
/// </summary>
public override Regex RegexPattern
{
get
{
return QueryRegex;
}
}
/// <summary>
/// Gets or sets DynamicParameter.
/// </summary>
public override dynamic DynamicParameter { get; set; }
/// <summary>
/// Gets the order in which this processor is to be used in a chain.
/// </summary>
public override int SortOrder { get; protected set; }
/// <summary>
/// Gets or sets any additional settings required by the processor.
/// </summary>
public override Dictionary<string, string> Settings { get; set; }
/// <summary>
/// The position in the original string where the first character of the captured substring was found.
/// </summary>
/// <param name="queryString">
/// The query string to search.
/// </param>
/// <returns>
/// The zero-based starting position in the original string where the captured substring was found.
/// </returns>
public override 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;
int[] constraints = match.Value.ToPositiveIntegerArray();
int x = constraints[0];
int y = constraints[1];
this.DynamicParameter = new Size(x, y);
}
index += 1;
}
}
return this.SortOrder;
}
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public override Image ProcessImage(ImageFactory factory)
{
double constrainedWidth = this.DynamicParameter.Width;
double constrainedHeight = this.DynamicParameter.Height;
Image original = factory.Image;
double width = original.Width;
double height = original.Height;
if (width > constrainedWidth || height > constrainedHeight)
{
double constraintRatio = constrainedHeight / constrainedWidth;
double originalRatio = height / width;
Size newSize = originalRatio < constraintRatio
? new Size((int)constrainedWidth, 0)
: new Size(0, (int)constrainedHeight);
int defaultMaxWidth;
int defaultMaxHeight;
int.TryParse(this.Settings["MaxWidth"], out defaultMaxWidth);
int.TryParse(this.Settings["MaxHeight"], out defaultMaxHeight);
return this.ResizeImage(factory, newSize.Width, newSize.Height, defaultMaxWidth, defaultMaxHeight);
}
return factory.Image;
}
#endregion
}
}

2
src/ImageProcessor/Processors/Crop.cs

@ -25,7 +25,7 @@ namespace ImageProcessor.Processors
/// The regular expression to search strings for.
/// <see cref="http://stackoverflow.com/a/6400969/427899"/>
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"crop=\d+-\d+-\d+-\d+", RegexOptions.Compiled);
private static readonly Regex QueryRegex = new Regex(@"crop=\d+[,-]\d+[,-]\d+[,-]\d+", RegexOptions.Compiled);
#region IGraphicsProcessor Members
/// <summary>

126
src/ImageProcessor/Processors/Resize.cs

@ -1,18 +1,18 @@
// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Resize.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// -----------------------------------------------------------------------
// <summary>
// Resizes an image to the given dimensions.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{
#region Using
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using ImageProcessor.Helpers.Extensions;
#endregion
@ -20,7 +20,7 @@ namespace ImageProcessor.Processors
/// <summary>
/// Resizes an image to the given dimensions.
/// </summary>
public class Resize : IGraphicsProcessor
public class Resize : ResizeBase
{
/// <summary>
/// The regular expression to search strings for.
@ -31,7 +31,7 @@ namespace ImageProcessor.Processors
/// <summary>
/// Gets the regular expression to search strings for.
/// </summary>
public Regex RegexPattern
public override Regex RegexPattern
{
get
{
@ -42,7 +42,7 @@ namespace ImageProcessor.Processors
/// <summary>
/// Gets or sets DynamicParameter.
/// </summary>
public dynamic DynamicParameter
public override dynamic DynamicParameter
{
get;
set;
@ -51,16 +51,16 @@ namespace ImageProcessor.Processors
/// <summary>
/// Gets the order in which this processor is to be used in a chain.
/// </summary>
public int SortOrder
public override int SortOrder
{
get;
private set;
protected set;
}
/// <summary>
/// Gets or sets any additional settings required by the processor.
/// </summary>
public Dictionary<string, string> Settings
public override Dictionary<string, string> Settings
{
get;
set;
@ -75,7 +75,7 @@ namespace ImageProcessor.Processors
/// <returns>
/// The zero-based starting position in the original string where the captured substring was found.
/// </returns>
public int MatchRegexIndex(string queryString)
public override int MatchRegexIndex(string queryString)
{
int index = 0;
@ -92,7 +92,7 @@ namespace ImageProcessor.Processors
// Set the index on the first instance only.
this.SortOrder = match.Index;
}
// Match syntax
if (match.Value.Contains("width"))
{
@ -102,7 +102,7 @@ namespace ImageProcessor.Processors
{
size.Height = match.Value.ToPositiveIntegerArray()[0];
}
index += 1;
}
}
@ -121,96 +121,18 @@ namespace ImageProcessor.Processors
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public Image ProcessImage(ImageFactory factory)
public override Image ProcessImage(ImageFactory factory)
{
Bitmap newImage = null;
Image image = factory.Image;
try
{
int width = this.DynamicParameter.Width ?? 0;
int height = this.DynamicParameter.Height ?? 0;
int sourceWidth = image.Width;
int sourceHeight = image.Height;
int defaultMaxWidth;
int defaultMaxHeight;
int.TryParse(this.Settings["MaxWidth"], out defaultMaxWidth);
int.TryParse(this.Settings["MaxHeight"], out defaultMaxHeight);
int maxWidth = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue;
int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue;
// If height or width is not passed we assume that the standard ratio is to be kept.
if (height == 0)
{
// Bit of simple fractional maths here.
float percentWidth = Math.Abs(width / (float)sourceWidth);
height = (int)Math.Floor(sourceHeight * percentWidth);
}
if (width == 0)
{
float percentHeight = Math.Abs(height / (float)sourceHeight);
width = (int)Math.Floor(sourceWidth * percentHeight);
}
if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight)
{
// Dont use an object initializer here.
newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
newImage.Tag = image.Tag;
int width = this.DynamicParameter.Width ?? 0;
int height = this.DynamicParameter.Height ?? 0;
using (Graphics graphics = Graphics.FromImage(newImage))
{
// We want to use two different blending algorithms for enlargement/shrinking.
// Bicubic is better enlarging for whilst Bilinear is better for shrinking.
// http://www.codinghorror.com/blog/2007/07/better-image-resizing.html
if (image.Width < width && image.Height < height)
{
// We are making it larger.
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
}
else
{
// We are making it smaller.
graphics.SmoothingMode = SmoothingMode.None;
// Contrary to everything I have read bicubic is producing the best results.
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.None;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
}
// An unwanted border appears when using InterpolationMode.HighQualityBicubic to resize the image
// as the algorithm appears to be pulling averaging detail from surFlooring 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(0, 0, width, height);
graphics.DrawImage(image, destRect, 0, 0, sourceWidth, sourceHeight, GraphicsUnit.Pixel, wrapMode);
}
// Reassign the image.
image.Dispose();
image = newImage;
}
}
}
catch
{
if (newImage != null)
{
newImage.Dispose();
}
}
int defaultMaxWidth;
int defaultMaxHeight;
int.TryParse(this.Settings["MaxWidth"], out defaultMaxWidth);
int.TryParse(this.Settings["MaxHeight"], out defaultMaxHeight);
return image;
return this.ResizeImage(factory, width, height, defaultMaxWidth, defaultMaxHeight);
}
#endregion
}
}

179
src/ImageProcessor/Processors/ResizeBase.cs

@ -0,0 +1,179 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ResizeBase.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The resize base for inheriting resizable methods from.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{
#region Using
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
#endregion
/// <summary>
/// The resize base for inheriting resizable methods from.
/// </summary>
public abstract class ResizeBase : IGraphicsProcessor
{
#region IGraphicsProcessor Members
/// <summary>
/// Gets the regular expression to search strings for.
/// </summary>
public abstract Regex RegexPattern { get; }
/// <summary>
/// Gets or sets DynamicParameter.
/// </summary>
public abstract dynamic DynamicParameter { get; set; }
/// <summary>
/// Gets or sets the order in which this processor is to be used in a chain.
/// </summary>
public abstract int SortOrder { get; protected set; }
/// <summary>
/// Gets or sets any additional settings required by the processor.
/// </summary>
public abstract Dictionary<string, string> Settings { get; set; }
/// <summary>
/// The position in the original string where the first character of the captured substring was found.
/// </summary>
/// <param name="queryString">
/// The query string to search.
/// </param>
/// <returns>
/// The zero-based starting position in the original string where the captured substring was found.
/// </returns>
public abstract int MatchRegexIndex(string queryString);
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public abstract Image ProcessImage(ImageFactory factory);
/// <summary>
/// The resize image.
/// </summary>
/// <param name="factory">
/// The the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <param name="width">
/// The width to resize the image to.
/// </param>
/// <param name="height">
/// The height to resize the image to.
/// </param>
/// <param name="defaultMaxWidth">
/// The default max width to resize the image to.
/// </param>
/// <param name="defaultMaxHeight">
/// The default max height to resize the image to.
/// </param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
protected Image ResizeImage(ImageFactory factory, int width, int height, int defaultMaxWidth, int defaultMaxHeight)
{
Bitmap newImage = null;
Image image = factory.Image;
try
{
int sourceWidth = image.Width;
int sourceHeight = image.Height;
int maxWidth = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue;
int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue;
// If height or width is not passed we assume that the standard ratio is to be kept.
if (height == 0)
{
// Bit of simple fractional maths here.
float percentWidth = Math.Abs(width / (float)sourceWidth);
height = (int)Math.Floor(sourceHeight * percentWidth);
}
if (width == 0)
{
float percentHeight = Math.Abs(height / (float)sourceHeight);
width = (int)Math.Floor(sourceWidth * percentHeight);
}
if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight)
{
// Dont use an object initializer here.
newImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
newImage.Tag = image.Tag;
using (Graphics graphics = Graphics.FromImage(newImage))
{
// We want to use two different blending algorithms for enlargement/shrinking.
// Bicubic is better enlarging for whilst Bilinear is better for shrinking.
// http://www.codinghorror.com/blog/2007/07/better-image-resizing.html
if (image.Width < width && image.Height < height)
{
// We are making it larger.
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
}
else
{
// We are making it smaller.
graphics.SmoothingMode = SmoothingMode.None;
// Contrary to everything I have read bicubic is producing the best results.
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.None;
graphics.CompositingQuality = CompositingQuality.HighSpeed;
}
// An unwanted border appears when using InterpolationMode.HighQualityBicubic to resize the image
// as the algorithm appears to be pulling averaging detail from surFlooring 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(0, 0, width, height);
graphics.DrawImage(image, destRect, 0, 0, sourceWidth, sourceHeight, GraphicsUnit.Pixel, wrapMode);
}
// Reassign the image.
image.Dispose();
image = newImage;
}
}
}
catch
{
if (newImage != null)
{
newImage.Dispose();
}
}
return image;
}
#endregion
}
}

4
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.7.0.3")]
[assembly: AssemblyFileVersion("1.7.0.3")]
[assembly: AssemblyVersion("1.7.1.1")]
[assembly: AssemblyFileVersion("1.7.1.1")]

BIN
src/Nuget/ImageProcessor.1.7.0.0.nupkg

Binary file not shown.

BIN
src/Nuget/ImageProcessor.1.7.0.1.nupkg

Binary file not shown.

BIN
src/Nuget/ImageProcessor.1.7.0.2.nupkg

Binary file not shown.

BIN
src/Nuget/ImageProcessor.1.7.0.3.nupkg

Binary file not shown.

BIN
src/Nuget/ImageProcessor.1.7.1.1.nupkg

Binary file not shown.

1
src/Nuget/ImageProcessor.Web.2.3.0.3.nupkg.REMOVED.git-id

@ -1 +0,0 @@
0a367af8c6588fe2be54ef5950820a7f06f7b0f1

1
src/Nuget/ImageProcessor.Web.2.3.0.4.nupkg.REMOVED.git-id

@ -1 +0,0 @@
129834a775acc5e2bfe85dc7db9edd37b9219e43

1
src/Nuget/ImageProcessor.Web.2.3.0.5.nupkg.REMOVED.git-id

@ -1 +0,0 @@
9d6097d930bbf60f2d333f80e7c916759a3c3f0c

1
src/Nuget/ImageProcessor.Web.2.3.0.6.nupkg.REMOVED.git-id

@ -0,0 +1 @@
7f1cb06ddbb5a91892188c8a18109d8db0f76115

6
src/TestWebsites/NET4/Web.config

@ -83,6 +83,12 @@
<setting key="MaxHeight" value="768" />
</settings>
</plugin>
<plugin name="Constrain">
<settings>
<setting key="MaxWidth" value="3000"/>
<setting key="MaxHeight" value="3000"/>
</settings>
</plugin>
</plugins>
</processing>
</imageProcessor>

4
src/TestWebsites/NET45/Test_Website_NET45/Test_Website_NET45.csproj

@ -165,7 +165,9 @@
<Folder Include="Models\" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />
<Content Include="packages.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Views\_ViewStart.cshtml" />

134
src/TestWebsites/NET45/Test_Website_NET45/Web.config

@ -5,80 +5,86 @@
-->
<configuration>
<configSections>
<sectionGroup name="imageProcessor">
<section name="security" requirePermission="false" type="ImageProcessor.Web.Config.ImageSecuritySection, ImageProcessor.Web"/>
<section name="processing" requirePermission="false" type="ImageProcessor.Web.Config.ImageProcessingSection, ImageProcessor.Web"/>
<section name="cache" requirePermission="false" type="ImageProcessor.Web.Config.ImageCacheSection, ImageProcessor.Web"/>
</sectionGroup>
</configSections>
<configSections>
<sectionGroup name="imageProcessor">
<section name="security" requirePermission="false" type="ImageProcessor.Web.Config.ImageSecuritySection, ImageProcessor.Web"/>
<section name="processing" requirePermission="false" type="ImageProcessor.Web.Config.ImageProcessingSection, ImageProcessor.Web"/>
<section name="cache" requirePermission="false" type="ImageProcessor.Web.Config.ImageCacheSection, ImageProcessor.Web"/>
</sectionGroup>
</configSections>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<system.web>
<httpRuntime targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<compilation debug="true" targetFramework="4.5" />
<compilation debug="true" targetFramework="4.5" />
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<httpModules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
</httpModules>
<httpModules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
</httpModules>
</system.web>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<modules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
</modules>
<modules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
</modules>
</system.webServer>
</system.webServer>
<imageProcessor>
<security allowRemoteDownloads="true" timeout="300000" maxBytes="524288" remotePrefix="/remote.axd">
<whiteList>
<add url="http://images.mymovies.net"/>
<add url="http://www.theworldeffect.com" />
</whiteList>
</security>
<cache virtualPath="~/app_data/cache" maxDays="56"/>
<processing>
<plugins>
<plugin name="Resize">
<settings>
<setting key="MaxWidth" value="3000"/>
<setting key="MaxHeight" value="3000"/>
</settings>
</plugin>
</plugins>
</processing>
</imageProcessor>
<imageProcessor>
<security allowRemoteDownloads="true" timeout="300000" maxBytes="524288" remotePrefix="/remote.axd">
<whiteList>
<add url="http://images.mymovies.net"/>
<add url="http://www.theworldeffect.com" />
</whiteList>
</security>
<cache virtualPath="~/app_data/cache" maxDays="56"/>
<processing>
<plugins>
<plugin name="Resize">
<settings>
<setting key="MaxWidth" value="3000"/>
<setting key="MaxHeight" value="3000"/>
</settings>
</plugin>
<plugin name="Constrain">
<settings>
<setting key="MaxWidth" value="3000"/>
<setting key="MaxHeight" value="3000"/>
</settings>
</plugin>
</plugins>
</processing>
</imageProcessor>
</configuration>

Loading…
Cancel
Save