Browse Source

Updating from dev

Former-commit-id: e8688a287452d9f57e9692bc7d7028d19eb7b801
pull/17/head
James South 12 years ago
parent
commit
22fc4bbc6c
  1. 6
      build/Build.bat
  2. 8
      build/NuSpecs/ImageProcessor.Web.Config.nuspec
  3. 8
      build/NuSpecs/ImageProcessor.Web.nuspec
  4. 2
      build/NuSpecs/ImageProcessor.nuspec
  5. 7
      src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj
  6. 4
      src/ImageProcessor.Web/NET4/app.config
  7. 2
      src/ImageProcessor.Web/NET4/packages.config
  8. 3
      src/ImageProcessor.Web/NET45/Caching/CacheIndexer.cs
  9. 5
      src/ImageProcessor.Web/NET45/Caching/CachedImage.cs
  10. 159
      src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
  11. 40
      src/ImageProcessor.Web/NET45/Configuration/Resources/processing - Copy.config
  12. 1
      src/ImageProcessor.Web/NET45/Configuration/Resources/processing.config
  13. 10
      src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
  14. 83
      src/ImageProcessor.Web/NET45/Processors/AutoRotate.cs
  15. 4
      src/ImageProcessor.Web/NET45/Properties/AssemblyInfo.cs
  16. 36
      src/ImageProcessor/ImageFactory.cs
  17. 2
      src/ImageProcessor/ImageProcessor.csproj
  18. 4
      src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs
  19. 89
      src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs
  20. 12
      src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
  21. 99
      src/ImageProcessor/Processors/AutoRotate.cs
  22. 4
      src/ImageProcessor/Properties/AssemblyInfo.cs
  23. 1
      src/ImageProcessor/Settings.StyleCop
  24. 1
      src/Images/rotate.jpg.REMOVED.git-id
  25. 6
      src/TestWebsites/NET4/Test_Website_MVC_NET4.csproj
  26. 10
      src/TestWebsites/NET4/Web.config
  27. 1
      src/TestWebsites/NET4/config/imageprocessor/processing.config
  28. 2
      src/TestWebsites/NET4/packages.config

6
build/Build.bat

@ -1,7 +1,7 @@
@ECHO OFF
SET version=1.9.2.0
SET webversion=3.2.6.0
SET webconfigversion=1.1.1.0
SET version=1.9.3.0
SET webversion=3.2.7.0
SET webconfigversion=1.1.2.0
ECHO Building ImageProcessor %version%, ImageProcess.Web %webversion% and ImageProcess.Web.Config %webconfigversion%

8
build/NuSpecs/ImageProcessor.Web.Config.nuspec

@ -21,12 +21,12 @@ Feedback is always welcome</description>
<tags>Image Imaging ASP Performance Processing HttpModule Cache Resize Rotate RoundedCorners Flip Crop Filter Effects Quality Watermark Alpha Vignette Saturation Brightness Contrast Gif Jpg Jpeg Bitmap Png Fluent GDI Gaussian Blur Sharpen Tint Quantizer Animated</tags>
<dependencies>
<group targetFramework=".NETFramework4.0">
<dependency id="ImageProcessor" version="1.9.2.0" />
<dependency id="ImageProcessor.Web" version="3.2.5.0" />
<dependency id="ImageProcessor" version="1.9.3.0" />
<dependency id="ImageProcessor.Web" version="3.2.7.0" />
</group>
<group targetFramework=".NETFramework4.5">
<dependency id="ImageProcessor" version="1.9.2.0" />
<dependency id="ImageProcessor.Web" version="3.2.5.0" />
<dependency id="ImageProcessor" version="1.9.3.0" />
<dependency id="ImageProcessor.Web" version="3.2.7.0" />
</group>
</dependencies>
</metadata>

8
build/NuSpecs/ImageProcessor.Web.nuspec

@ -22,15 +22,15 @@ Feedback is always welcome</description>
<releaseNotes />
<copyright>James South</copyright>
<language>en-GB</language>
<tags>Image Imaging ASP Performance Processing HttpModule Cache Resize Rotate RoundedCorners Flip Crop Filter Effects Quality Watermark Alpha Vignette Saturation Brightness Contrast Gif Jpg Jpeg Bitmap Png Fluent GDI Gaussian Blur Sharpen Tint Quantizer Animated</tags>
<tags>Image Imaging ASP Performance Processing HttpModule Cache Resize AutoRotate Rotate RoundedCorners Flip Crop Filter Effects Quality Watermark Alpha Vignette Saturation Brightness Contrast Gif Jpg Jpeg Bitmap Png Fluent GDI Gaussian Blur Sharpen Tint Quantizer Animated EXIF</tags>
<dependencies>
<group targetFramework=".NETFramework4.0">
<dependency id="Microsoft.Bcl.Async" version="1.0.168" />
<dependency id="Microsoft.Bcl" version="1.1.8" />
<dependency id="ImageProcessor" version="1.9.2.0" />
<dependency id="Microsoft.Bcl" version="1.1.9" />
<dependency id="ImageProcessor" version="1.9.3.0" />
</group>
<group targetFramework=".NETFramework4.5">
<dependency id="ImageProcessor" version="1.9.2.0" />
<dependency id="ImageProcessor" version="1.9.3.0" />
</group>
</dependencies>
</metadata>

2
build/NuSpecs/ImageProcessor.nuspec

@ -21,7 +21,7 @@ Feedback is always welcome.</description>
<releaseNotes />
<copyright>James South</copyright>
<language>en-GB</language>
<tags>Image Imaging ASP Performance Processing Resize Rotate RoundedCorners Flip Crop Filter Effects Quality Watermark Alpha Vignette Saturation Brightness Contrast Gif Jpg Jpeg Bitmap Png Fluent GDI Gaussian Blur Sharpen Tint Quantizer Animated</tags>
<tags>Image Imaging ASP Performance Processing Resize AutoRotate Rotate RoundedCorners Flip Crop Filter Effects Quality Watermark Alpha Vignette Saturation Brightness Contrast Gif Jpg Jpeg Bitmap Png Fluent GDI Gaussian Blur Sharpen Tint Quantizer Animated EXIF</tags>
</metadata>
<files>
<file src="..\_BuildOutput\ImageProcessor\lib\ImageProcessor.dll" target="lib\ImageProcessor.dll" />

7
src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj

@ -59,15 +59,16 @@
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO">
<HintPath>..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.IO.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.9\lib\net40\System.IO.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Runtime">
<HintPath>..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.Runtime.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.9\lib\net40\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Threading.Tasks">
<HintPath>..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.Threading.Tasks.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.9\lib\net40\System.Threading.Tasks.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Data" />

4
src/ImageProcessor.Web/NET4/app.config

@ -4,11 +4,11 @@
<assemblyBinding xmlns:bcl="urn:schemas-microsoft-com:bcl" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly bcl:name="System.Runtime">
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.6.9.0" newVersion="2.6.9.0" />
</dependentAssembly>
<dependentAssembly bcl:name="System.Threading.Tasks">
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.6.9.0" newVersion="2.6.9.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

2
src/ImageProcessor.Web/NET4/packages.config

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl" version="1.1.8" targetFramework="net40" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net40" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net40" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net40" />
</packages>

3
src/ImageProcessor.Web/NET45/Caching/CacheIndexer.cs

@ -114,8 +114,7 @@ namespace ImageProcessor.Web.Caching
{
Key = Path.GetFileNameWithoutExtension(cachePath),
Path = cachePath,
CreationTimeUtc = fileInfo.CreationTimeUtc,
LastWriteTimeUtc = fileInfo.LastWriteTimeUtc
CreationTimeUtc = fileInfo.CreationTimeUtc
};
}
}

5
src/ImageProcessor.Web/NET45/Caching/CachedImage.cs

@ -33,10 +33,5 @@ namespace ImageProcessor.Web.Caching
/// Gets or sets the creation time of the cached image.
/// </summary>
public DateTime CreationTimeUtc { get; set; }
/// <summary>
/// Gets or sets the last write time of the cached image.
/// </summary>
public DateTime LastWriteTimeUtc { get; set; }
}
}

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

@ -14,13 +14,12 @@ namespace ImageProcessor.Web.Caching
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using ImageProcessor.Core.Common.Extensions;
using ImageProcessor.Web.Configuration;
using ImageProcessor.Web.Helpers;
@ -52,8 +51,7 @@ namespace ImageProcessor.Web.Caching
/// <summary>
/// The absolute path to virtual cache path on the server.
/// </summary>
private static readonly string AbsoluteCachePath =
HostingEnvironment.MapPath(ImageProcessorConfiguration.Instance.VirtualCachePath);
private static readonly string AbsoluteCachePath = HostingEnvironment.MapPath(ImageProcessorConfig.Instance.VirtualCachePath);
/// <summary>
/// The request for the image.
@ -142,18 +140,14 @@ namespace ImageProcessor.Web.Caching
/// <summary>
/// Adds an image to the cache.
/// </summary>
/// <param name="creationAndLastWriteDateTimes">
/// The creation and last write times.
/// </param>
internal void AddImageToCache(Tuple<DateTime, DateTime> creationAndLastWriteDateTimes)
internal void AddImageToCache()
{
string key = Path.GetFileNameWithoutExtension(this.CachedPath);
CachedImage cachedImage = new CachedImage
{
Key = key,
Path = this.CachedPath,
CreationTimeUtc = creationAndLastWriteDateTimes.Item1,
LastWriteTimeUtc = creationAndLastWriteDateTimes.Item2
CreationTimeUtc = DateTime.UtcNow
};
CacheIndexer.Add(cachedImage);
@ -196,26 +190,7 @@ namespace ImageProcessor.Web.Caching
// Test now for locally requested files.
cachedImage = await CacheIndexer.GetValueAsync(path);
if (cachedImage != null)
{
FileInfo imageFileInfo = new FileInfo(this.requestPath);
if (imageFileInfo.Exists)
{
// Pull the latest info.
imageFileInfo.Refresh();
// Check to see if the last write time is different of whether the
// cached image is set to expire or if the max age is different.
if (!this.RoughDateTimeCompare(imageFileInfo.LastWriteTimeUtc, cachedImage.LastWriteTimeUtc)
|| this.IsExpired(cachedImage.CreationTimeUtc))
{
CacheIndexer.Remove(path);
isUpdated = true;
}
}
}
else
if (cachedImage == null)
{
// Nothing in the cache so we should return true.
isUpdated = true;
@ -225,38 +200,6 @@ 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()
{
DateTime dateTime = DateTime.UtcNow;
CachedImage cachedImage = await CacheIndexer.GetValueAsync(this.CachedPath);
if (cachedImage != null)
{
dateTime = cachedImage.LastWriteTimeUtc;
}
return dateTime;
}
/// <summary>
/// Sets the LastWriteTime of the cached file to match the original file.
/// </summary>
/// <returns>
/// The <see cref="T:System.DateTime"/> set to the last write time of the file.
/// </returns>
internal async Task<Tuple<DateTime, DateTime>> SetCachedLastWriteTimeAsync()
{
// Create Action delegate for SetCachedLastWriteTime.
return await TaskHelpers.Run(() => this.SetCachedLastWriteTime());
}
/// <summary>
/// Trims a cached folder ensuring that it does not exceed the maximum file count.
/// </summary>
@ -273,46 +216,6 @@ namespace ImageProcessor.Web.Caching
#endregion
#region Private
/// <summary>
/// Sets the LastWriteTime of the cached file to match the original file.
/// </summary>
/// <returns>
/// The <see cref="T:System.DateTime"/> of the original and cached file.
/// </returns>
private Tuple<DateTime, DateTime> SetCachedLastWriteTime()
{
FileInfo cachedFileInfo = new FileInfo(this.CachedPath);
// DateTime.Min explodes when used east of GMT.
DateTime baseDateTime = DateTime.UtcNow;
DateTime creationTime = baseDateTime;
DateTime lastWriteTime = baseDateTime;
if (this.isRemote)
{
if (cachedFileInfo.Exists)
{
creationTime = cachedFileInfo.CreationTimeUtc;
lastWriteTime = cachedFileInfo.LastWriteTimeUtc;
}
}
else
{
FileInfo imageFileInfo = new FileInfo(this.requestPath);
if (imageFileInfo.Exists && cachedFileInfo.Exists)
{
DateTime dateTime = imageFileInfo.LastWriteTimeUtc;
creationTime = cachedFileInfo.CreationTimeUtc;
cachedFileInfo.LastWriteTimeUtc = dateTime;
lastWriteTime = dateTime;
}
}
return new Tuple<DateTime, DateTime>(creationTime, lastWriteTime);
}
/// <summary>
/// Trims a cached folder ensuring that it does not exceed the maximum file count.
/// </summary>
@ -368,15 +271,43 @@ namespace ImageProcessor.Web.Caching
private string GetCachePath()
{
string cachedPath = string.Empty;
string streamHash = string.Empty;
if (AbsoluteCachePath != null)
{
try
{
if (new Uri(this.requestPath).IsFile)
{
// Get the hash for the filestream. That way we can ensure that if the image is
// updated but has the same name we will know.
FileInfo imageFileInfo = new FileInfo(this.requestPath);
if (imageFileInfo.Exists)
{
// Pull the latest info.
imageFileInfo.Refresh();
using (MD5 md5 = MD5.Create())
{
using (FileStream stream = File.OpenRead(imageFileInfo.FullName))
{
byte[] hash = md5.ComputeHash(stream);
streamHash = BitConverter.ToString(hash);
}
}
}
}
}
catch
{
streamHash = string.Empty;
}
// Use an sha1 hash of the full path including the querystring to create the image name.
// That name can also be used as a key for the cached image and we should be able to use
// The characters of that hash as subfolders.
string parsedExtension = ImageHelpers.GetExtension(this.fullPath);
string fallbackExtension = this.imageName.Substring(this.imageName.LastIndexOf(".", StringComparison.Ordinal) + 1);
string encryptedName = this.fullPath.ToSHA1Fingerprint();
string encryptedName = (streamHash + this.fullPath).ToSHA1Fingerprint();
// Collision rate of about 1 in 10000 for the folder structure.
string pathFromKey = string.Join("\\", encryptedName.ToCharArray().Take(6));
@ -392,28 +323,6 @@ namespace ImageProcessor.Web.Caching
return cachedPath;
}
/// <summary>
/// The rough date time compare.
/// </summary>
/// <param name="first">
/// The first.
/// </param>
/// <param name="second">
/// The second.
/// </param>
/// <returns>
/// The <see cref="bool"/> true if the DateTimes roughly compare; otherwise, false.
/// </returns>
private bool RoughDateTimeCompare(DateTime first, DateTime second)
{
if (first.ToString(CultureInfo.InvariantCulture) == second.ToString(CultureInfo.InvariantCulture))
{
return true;
}
return false;
}
/// <summary>
/// Gets a value indicating whether the given images creation date is out with
/// the prescribed limit.

40
src/ImageProcessor.Web/NET45/Configuration/Resources/processing - Copy.config

@ -1,40 +0,0 @@
<processing preserveExifMetaData="false">
<presets>
</presets>
<plugins autoLoadPlugins="true">
<plugin name="Alpha" type="ImageProcessor.Processors.Alpha, ImageProcessor"/>
<plugin name="Brightness" type="ImageProcessor.Processors.Brightness, ImageProcessor"/>
<plugin name="Contrast" type="ImageProcessor.Processors.Contrast, ImageProcessor"/>
<plugin name="Crop" type="ImageProcessor.Processors.Crop, ImageProcessor"/>
<plugin name="Filter" type="ImageProcessor.Processors.Filter, ImageProcessor"/>
<plugin name="Flip" type="ImageProcessor.Processors.Flip, ImageProcessor"/>
<plugin name="Format" type="ImageProcessor.Processors.Format, ImageProcessor"/>
<plugin name="GaussianBlur" type="ImageProcessor.Processors.GaussianBlur, ImageProcessor">
<settings>
<setting key="MaxSize" value="22"/>
<setting key="MaxSigma" value="5.1"/>
<setting key="MaxThreshold" value="100"/>
</settings>
</plugin>
<plugin name="GaussianSharpen" type="ImageProcessor.Processors.GaussianSharpen, ImageProcessor">
<settings>
<setting key="MaxSize" value="22"/>
<setting key="MaxSigma" value="5.1"/>
<setting key="MaxThreshold" value="100"/>
</settings>
</plugin>
<plugin name="Quality" type="ImageProcessor.Processors.Quality, ImageProcessor"/>
<plugin name="Resize" type="ImageProcessor.Processors.Resize, ImageProcessor">
<settings>
<setting key="MaxWidth" value="5000"/>
<setting key="MaxHeight" value="5000"/>
</settings>
</plugin>
<plugin name="Rotate" type="ImageProcessor.Processors.Rotate, ImageProcessor"/>
<plugin name="RoundedCorners" type="ImageProcessor.Processors.RoundedCorners, ImageProcessor"/>
<plugin name="Saturation" type="ImageProcessor.Processors.Saturation, ImageProcessor"/>
<plugin name="Tint" type="ImageProcessor.Processors.Tint, ImageProcessor"/>
<plugin name="Vignette" type="ImageProcessor.Processors.Vignette, ImageProcessor"/>
<plugin name="Watermark" type="ImageProcessor.Processors.Watermark, ImageProcessor"/>
</plugins>
</processing>

1
src/ImageProcessor.Web/NET45/Configuration/Resources/processing.config

@ -3,6 +3,7 @@
</presets>
<plugins autoLoadPlugins="true">
<plugin name="Alpha" type="ImageProcessor.Web.Processors.Alpha, ImageProcessor.Web"/>
<plugin name="AutoRotate" type="ImageProcessor.Web.Processors.AutoRotate, ImageProcessor.Web"/>
<plugin name="Brightness" type="ImageProcessor.Web.Processors.Brightness, ImageProcessor.Web"/>
<plugin name="Contrast" type="ImageProcessor.Web.Processors.Contrast, ImageProcessor.Web"/>
<plugin name="Crop" type="ImageProcessor.Web.Processors.Crop, ImageProcessor.Web"/>

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

@ -416,11 +416,8 @@ namespace ImageProcessor.Web.HttpModules
// Store the response type in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;
// Ensure that the LastWriteTime property of the source and cached file match.
Tuple<DateTime, DateTime> creationAndLastWriteDateTimes = await cache.SetCachedLastWriteTimeAsync();
// Add to the cache.
cache.AddImageToCache(creationAndLastWriteDateTimes);
cache.AddImageToCache();
// Trim the cache.
await cache.TrimCachedFolderAsync(cachedPath);
@ -456,11 +453,8 @@ namespace ImageProcessor.Web.HttpModules
// Store the response type in the context for later retrieval.
context.Items[CachedResponseTypeKey] = imageFactory.CurrentImageFormat.MimeType;
// Ensure that the LastWriteTime property of the source and cached file match.
Tuple<DateTime, DateTime> creationAndLastWriteDateTimes = await cache.SetCachedLastWriteTimeAsync();
// Add to the cache.
cache.AddImageToCache(creationAndLastWriteDateTimes);
cache.AddImageToCache();
// Trim the cache.
await cache.TrimCachedFolderAsync(cachedPath);

83
src/ImageProcessor.Web/NET45/Processors/AutoRotate.cs

@ -0,0 +1,83 @@
namespace ImageProcessor.Web.Processors
{
using System.Text.RegularExpressions;
using ImageProcessor.Processors;
/// <summary>
/// Performs auto-rotation to ensure that EXIF defined rotation is reflected in
/// the final image.
/// </summary>
public class AutoRotate : IWebGraphicsProcessor
{
/// <summary>
/// The regular expression to search strings for.
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"autorotate=true", RegexOptions.Compiled);
/// <summary>
/// Initializes a new instance of the <see cref="AutoRotate"/> class.
/// </summary>
public AutoRotate()
{
this.Processor = new ImageProcessor.Processors.AutoRotate();
}
/// <summary>
/// Gets the regular expression to search strings for.
/// </summary>
public Regex RegexPattern
{
get
{
return QueryRegex;
}
}
/// <summary>
/// Gets the order in which this processor is to be used in a chain.
/// </summary>
public int SortOrder
{
get;
private set;
}
/// <summary>
/// Gets the associated graphics processor.
/// </summary>
public IGraphicsProcessor Processor { get; private 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 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;
}
index += 1;
}
}
return this.SortOrder;
}
}
}

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

@ -35,5 +35,5 @@ using ImageProcessor.Web.HttpModules;
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("3.2.6.0")]
[assembly: AssemblyFileVersion("3.2.6.0")]
[assembly: AssemblyVersion("3.2.7.0")]
[assembly: AssemblyFileVersion("3.2.7.0")]

36
src/ImageProcessor/ImageFactory.cs

@ -169,12 +169,10 @@ namespace ImageProcessor
format.Quality = DefaultQuality;
format.IsIndexed = ImageUtils.IsIndexed(this.Image);
if (this.PreserveExifData)
// Always load the data.
foreach (PropertyItem propertyItem in this.Image.PropertyItems)
{
foreach (PropertyItem propertyItem in this.Image.PropertyItems)
{
this.ExifPropertyItems[propertyItem.Id] = propertyItem;
}
this.ExifPropertyItems[propertyItem.Id] = propertyItem;
}
this.ShouldProcess = true;
@ -239,12 +237,10 @@ namespace ImageProcessor
this.OriginalExtension = Path.GetExtension(this.ImagePath);
if (this.PreserveExifData)
// Always load the data.
foreach (PropertyItem propertyItem in this.Image.PropertyItems)
{
foreach (PropertyItem propertyItem in this.Image.PropertyItems)
{
this.ExifPropertyItems[propertyItem.Id] = propertyItem;
}
this.ExifPropertyItems[propertyItem.Id] = propertyItem;
}
this.ShouldProcess = true;
@ -325,6 +321,24 @@ namespace ImageProcessor
return this;
}
/// <summary>
/// Performs auto-rotation to ensure that EXIF defined rotation is reflected in
/// the final image.
/// </summary>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public ImageFactory AutoRotate()
{
if (this.ShouldProcess)
{
AutoRotate autoRotate = new AutoRotate();
this.ApplyProcessor(autoRotate.ProcessImage);
}
return this;
}
/// <summary>
/// Changes the brightness of the current image.
/// </summary>
@ -413,7 +427,7 @@ namespace ImageProcessor
{
if (this.ShouldProcess)
{
CropLayer cropLayer = new CropLayer(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom, CropMode.Pixels);
CropLayer cropLayer = new CropLayer(rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height, CropMode.Pixels);
return this.Crop(cropLayer);
}

2
src/ImageProcessor/ImageProcessor.csproj

@ -76,7 +76,6 @@
<Compile Include="Imaging\CropLayer.cs" />
<Compile Include="Imaging\CropMode.cs" />
<Compile Include="Imaging\ExifPropertyTag.cs" />
<Compile Include="Imaging\Filters\MatrixFilterRegexAttribute.cs" />
<Compile Include="Imaging\Filters\MatrixFilters.cs" />
<Compile Include="Imaging\Formats\BitmapFormat.cs" />
<Compile Include="Imaging\Formats\TiffFormat.cs" />
@ -112,6 +111,7 @@
<Compile Include="Imaging\OctreeQuantizer.cs" />
<Compile Include="Processors\Alpha.cs" />
<Compile Include="Processors\BackgroundColor.cs" />
<Compile Include="Processors\AutoRotate.cs" />
<Compile Include="Processors\GaussianBlur.cs" />
<Compile Include="Processors\Brightness.cs" />
<Compile Include="Processors\Contrast.cs" />

4
src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs

@ -11,10 +11,6 @@
namespace ImageProcessor.Imaging.Filters
{
#region Using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
#endregion

89
src/ImageProcessor/Imaging/Filters/ColorMatrixes.cs

@ -21,37 +21,38 @@ namespace ImageProcessor.Imaging.Filters
internal static class ColorMatrixes
{
/// <summary>
/// Gets Sepia.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the sepia filter.
/// </summary>
internal static ColorMatrix Sepia
{
get
{
return new ColorMatrix(
new float[][]
return
new ColorMatrix(
new[]
{
new float[] { .393f, .349f, .272f, 0, 0 },
new float[] { .769f, .686f, .534f, 0, 0 },
new float[] { .189f, .168f, .131f, 0, 0 },
new[] { .393f, .349f, .272f, 0, 0 },
new[] { .769f, .686f, .534f, 0, 0 },
new[] { .189f, .168f, .131f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
});
}
}
/// <summary>
/// Gets BlackWhite.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the black and white filter.
/// </summary>
internal static ColorMatrix BlackWhite
{
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 1.5f, 1.5f, 1.5f, 0, 0 },
new float[] { 1.5f, 1.5f, 1.5f, 0, 0 },
new float[] { 1.5f, 1.5f, 1.5f, 0, 0 },
new[] { 1.5f, 1.5f, 1.5f, 0, 0 },
new[] { 1.5f, 1.5f, 1.5f, 0, 0 },
new[] { 1.5f, 1.5f, 1.5f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { -1, -1, -1, 0, 1 }
});
@ -59,57 +60,56 @@ namespace ImageProcessor.Imaging.Filters
}
/// <summary>
/// Gets Polaroid.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the polaroid filter.
/// </summary>
internal static ColorMatrix Polaroid
{
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 1.638f, -0.062f, -0.262f, 0, 0 },
new float[] { -0.122f, 1.378f, -0.122f, 0, 0 },
new float[] { 1.016f, -0.016f, 1.383f, 0, 0 },
new[] { 1.638f, -0.062f, -0.262f, 0, 0 },
new[] { -0.122f, 1.378f, -0.122f, 0, 0 },
new[] { 1.016f, -0.016f, 1.383f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0.06f, -0.05f, -0.05f, 0, 1 }
new[] { 0.06f, -0.05f, -0.05f, 0, 1 }
});
}
}
/// <summary>
/// Gets Lomograph.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the lomograph filter.
/// </summary>
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
internal static ColorMatrix Lomograph
{
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 1.50f, 0, 0, 0, 0 },
new float[] { 0, 1.45f, 0, 0, 0 },
new float[] { 0, 0, 1.09f, 0, 0 },
new[] { 1.50f, 0, 0, 0, 0 },
new[] { 0, 1.45f, 0, 0, 0 },
new[] { 0, 0, 1.09f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { -0.10f, 0.05f, -0.08f, 0, 1 }
new[] { -0.10f, 0.05f, -0.08f, 0, 1 }
});
}
}
/// <summary>
/// Gets GreyScale.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the greyscale filter.
/// </summary>
internal static ColorMatrix GreyScale
{
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { .33f, .33f, .33f, 0, 0 },
new float[] { .59f, .59f, .59f, 0, 0 },
new float[] { .11f, .11f, .11f, 0, 0 },
new[] { .33f, .33f, .33f, 0, 0 },
new[] { .59f, .59f, .59f, 0, 0 },
new[] { .11f, .11f, .11f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
@ -117,14 +117,14 @@ namespace ImageProcessor.Imaging.Filters
}
/// <summary>
/// Gets Invert.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the invert filter.
/// </summary>
internal static ColorMatrix Invert
{
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { -1, 0, 0, 0, 0 },
new float[] { 0, -1, 0, 0, 0 },
@ -136,7 +136,7 @@ namespace ImageProcessor.Imaging.Filters
}
/// <summary>
/// Gets HiSatch.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the high saturation filter.
/// </summary>
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
internal static ColorMatrix HiSatch
@ -144,7 +144,7 @@ namespace ImageProcessor.Imaging.Filters
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 3, -1, -1, 0, 0 },
new float[] { -1, 3, -1, 0, 0 },
@ -156,7 +156,7 @@ namespace ImageProcessor.Imaging.Filters
}
/// <summary>
/// Gets LoSatch.
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the low saturation filter.
/// </summary>
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
internal static ColorMatrix LoSatch
@ -164,19 +164,19 @@ namespace ImageProcessor.Imaging.Filters
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 1, 0, 0, 0, 0 },
new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { .25f, .25f, .25f, 0, 1 }
new[] { .25f, .25f, .25f, 0, 1 }
});
}
}
/// <summary>
/// Gets <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the high pass
/// Gets the <see cref="T:System.Drawing.Imaging.ColorMatrix"/> for generating the high pass
/// on the comic book filter.
/// </summary>
internal static ColorMatrix ComicHigh
@ -184,11 +184,11 @@ namespace ImageProcessor.Imaging.Filters
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 2, -0.5f, -0.5f, 0, 0 },
new float[] { -0.5f, 2, -0.5f, 0, 0 },
new float[] { -0.5f, -0.5f, 2, 0, 0 },
new[] { 2, -0.5f, -0.5f, 0, 0 },
new[] { -0.5f, 2, -0.5f, 0, 0 },
new[] { -0.5f, -0.5f, 2, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
@ -204,16 +204,15 @@ namespace ImageProcessor.Imaging.Filters
get
{
return new ColorMatrix(
new float[][]
new[]
{
new float[] { 1, 0, 0, 0, 0 },
new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { .075f, .075f, .075f, 0, 1 }
new[] { .075f, .075f, .075f, 0, 1 }
});
}
}
}
}

12
src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs

@ -17,9 +17,7 @@ namespace ImageProcessor.Imaging.Filters
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using ImageProcessor.Core.Common.Extensions;
#endregion
/// <summary>
@ -38,16 +36,6 @@ namespace ImageProcessor.Imaging.Filters
/// </summary>
Blue = 0,
/// <summary>
/// The green channel
/// </summary>
Green = 1,
/// <summary>
/// The red channel
/// </summary>
Red = 2,
/// <summary>
/// The alpha channel
/// </summary>

99
src/ImageProcessor/Processors/AutoRotate.cs

@ -0,0 +1,99 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AutoRotate.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Performs auto-rotation to ensure that EXIF defined rotation is reflected in
// the final image.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{
using System.Collections.Generic;
using System.Drawing;
using ImageProcessor.Imaging;
/// <summary>
/// Performs auto-rotation to ensure that EXIF defined rotation is reflected in
/// the final image.
/// </summary>
public class AutoRotate : IGraphicsProcessor
{
/// <summary>
/// Gets or sets DynamicParameter.
/// </summary>
public dynamic DynamicParameter
{
get;
set;
}
/// <summary>
/// Gets or sets any additional settings required by the processor.
/// </summary>
public Dictionary<string, string> Settings
{
get;
set;
}
/// <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 Image ProcessImage(ImageFactory factory)
{
Bitmap newImage = null;
Image image = factory.Image;
try
{
const int Orientation = (int)ExifPropertyTag.Orientation;
if (!factory.PreserveExifData && factory.ExifPropertyItems.ContainsKey(Orientation))
{
newImage = new Bitmap(image);
int rotationValue = factory.ExifPropertyItems[Orientation].Value[0];
switch (rotationValue)
{
case 1: // Landscape, do nothing
break;
case 8: // Rotated 90 right
// De-rotate:
newImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
break;
case 3: // Bottoms up
newImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
break;
case 6: // Rotated 90 left
newImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
break;
}
// Reassign the image.
image.Dispose();
image = newImage;
}
}
catch
{
if (newImage != null)
{
newImage.Dispose();
}
}
return image;
}
}
}

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.9.2.0")]
[assembly: AssemblyFileVersion("1.9.2.0")]
[assembly: AssemblyVersion("1.9.3.0")]
[assembly: AssemblyFileVersion("1.9.3.0")]

1
src/ImageProcessor/Settings.StyleCop

@ -9,6 +9,7 @@
<Value>exif</Value>
<Value>halftoning</Value>
<Value>lomograph</Value>
<Value>Lomograph</Value>
<Value>octree</Value>
<Value>png</Value>
<Value>quantizer</Value>

1
src/Images/rotate.jpg.REMOVED.git-id

@ -0,0 +1 @@
406a6a7916628c0c0bea8243565a7162ebd5a505

6
src/TestWebsites/NET4/Test_Website_MVC_NET4.csproj

@ -70,14 +70,14 @@
</Reference>
<Reference Include="System.Data.Entity" />
<Reference Include="System.IO">
<HintPath>..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.IO.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.9\lib\net40\System.IO.dll</HintPath>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Runtime">
<HintPath>..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.Runtime.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.9\lib\net40\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks">
<HintPath>..\..\packages\Microsoft.Bcl.1.1.8\lib\net40\System.Threading.Tasks.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Bcl.1.1.9\lib\net40\System.Threading.Tasks.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />

10
src/TestWebsites/NET4/Web.config

@ -46,7 +46,7 @@
</namespaces>
</pages>
<httpModules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web" />
</httpModules>
<!--Set the trust level.-->
<!--<trust level="Medium"/>-->
@ -63,13 +63,13 @@
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<dependentAssembly name="System.Runtime">
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.6.9.0" newVersion="2.6.9.0" />
</dependentAssembly>
<dependentAssembly>
<dependentAssembly name="System.Threading.Tasks">
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
<bindingRedirect oldVersion="0.0.0.0-2.6.9.0" newVersion="2.6.9.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

1
src/TestWebsites/NET4/config/imageprocessor/processing.config

@ -5,6 +5,7 @@
</presets>
<plugins autoLoadPlugins="true">
<plugin name="Alpha" type="ImageProcessor.Processors.Alpha, ImageProcessor"/>
<plugin name="AutoRotate" type="ImageProcessor.Processors.AutoRotate, ImageProcessor"/>
<plugin name="Brightness" type="ImageProcessor.Processors.Brightness, ImageProcessor"/>
<plugin name="Contrast" type="ImageProcessor.Processors.Contrast, ImageProcessor"/>
<plugin name="Crop" type="ImageProcessor.Processors.Crop, ImageProcessor"/>

2
src/TestWebsites/NET4/packages.config

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl" version="1.1.8" targetFramework="net40" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net40" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net40" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net40" />
</packages>
Loading…
Cancel
Save