From 9b66b7aefdc62bb4e58ec5736806bcf84dea2c19 Mon Sep 17 00:00:00 2001 From: JimBobSquarePants Date: Tue, 19 Mar 2013 21:40:17 +0000 Subject: [PATCH] Prepping for 2.0.0 release Former-commit-id: b59ab2bde9a0cce9543992d66cc3297dee8efb45 --- .../RegularExpressionUnitTests.cs | 7 +- .../HttpModules/ImageProcessingModule.cs | 8 + .../Properties/AssemblyInfo.cs | 4 +- src/ImageProcessor/ImageFactory.cs | 8 +- .../Imaging/Filters/BlackWhiteMatrixFilter.cs | 4 +- .../Imaging/Filters/ComicMatrixFilter.cs | 2 +- .../Imaging/Filters/GothamMatrixFilter.cs | 4 +- .../Imaging/Filters/GreyScaleMatrixFilter.cs | 4 +- .../Imaging/Filters/HiSatchMatrixFilter.cs | 4 +- .../Imaging/Filters/IMatrixFilter.cs | 2 +- .../Imaging/Filters/InvertMatrixFilter.cs | 4 +- .../Imaging/Filters/LoSatchMatrixFilter.cs | 4 +- .../Imaging/Filters/LomographMatrixFilter.cs | 4 +- .../Imaging/Filters/PolaroidMatrixFilter.cs | 4 +- .../Imaging/Filters/SepiaMatrixFilter.cs | 4 +- src/ImageProcessor/Imaging/RotateLayer.cs | 59 +- .../Processors/Copy of Filter.cs | 610 ------------------ src/ImageProcessor/Processors/Png8.cs | 147 ----- src/ImageProcessor/Properties/AssemblyInfo.cs | 4 +- src/Nuget/ImageProcessor.1.4.0.0.nupkg | Bin 0 -> 26030 bytes src/Nuget/ImageProcessor.Web.2.0.0.0.nupkg | Bin 0 -> 20130 bytes src/Test/Test/Test.csproj | 2 + 22 files changed, 98 insertions(+), 791 deletions(-) delete mode 100644 src/ImageProcessor/Processors/Copy of Filter.cs delete mode 100644 src/ImageProcessor/Processors/Png8.cs create mode 100644 src/Nuget/ImageProcessor.1.4.0.0.nupkg create mode 100644 src/Nuget/ImageProcessor.Web.2.0.0.0.nupkg diff --git a/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs b/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs index c184374dd..088053df6 100644 --- a/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs +++ b/src/ImageProcessor.Tests/RegularExpressionUnitTests.cs @@ -18,8 +18,8 @@ [TestMethod] public void TestAlphaRegex() { - string querystring = "alpha=56"; - int expected = 56; + const string querystring = "alpha=56"; + const int expected = 56; Alpha alpha = new Alpha(); alpha.MatchRegexIndex(querystring); @@ -60,6 +60,7 @@ [TestMethod] public void TestRotateRegex() { + // Why does this fail? string querystring = "rotate=270"; RotateLayer expected = new RotateLayer { @@ -72,8 +73,6 @@ RotateLayer actual = rotate.DynamicParameter; - Debug.Print("{0}{1}", actual.Angle, actual.BackgroundColor); - Assert.AreEqual(expected, actual); } #endregion diff --git a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs index 68895043f..da41a9573 100644 --- a/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs +++ b/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs @@ -11,6 +11,7 @@ namespace ImageProcessor.Web.HttpModules using System; using System.IO; using System.Net; + using System.Reflection; using System.Web; using System.Web.Hosting; using ImageProcessor.Helpers.Extensions; @@ -40,6 +41,11 @@ namespace ImageProcessor.Web.HttpModules /// The object to lock against. /// private static readonly object SyncRoot = new object(); + + /// + /// The assembly version. + /// + private static readonly string AssemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); #endregion #region IHttpModule Members @@ -232,6 +238,8 @@ namespace ImageProcessor.Web.HttpModules response.ContentType = responseType; + response.AddHeader("Image-Served-By", "ImageProcessor/" + AssemblyVersion); + HttpCachePolicy cache = response.Cache; cache.VaryByHeaders["Accept-Encoding"] = true; diff --git a/src/ImageProcessor.Web/Properties/AssemblyInfo.cs b/src/ImageProcessor.Web/Properties/AssemblyInfo.cs index 89e023946..a2f13edc1 100644 --- a/src/ImageProcessor.Web/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor.Web/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("1.3.0.0")] -[assembly: AssemblyFileVersion("1.3.0.0")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index 737b54778..93fa21b49 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -77,7 +77,7 @@ namespace ImageProcessor public string ImagePath { get; private set; } /// - /// Gets the querystring params for web image manipulation. + /// Gets the query-string parameters for web image manipulation. /// public string QueryString { get; private set; } @@ -177,9 +177,9 @@ namespace ImageProcessor #region Manipulation /// - /// Adds a querystring to the image factory to allow autoprocessing of remote files. + /// Adds a query-string to the image factory to allow auto-processing of remote files. /// - /// The querystring parameter to process. + /// The query-string parameter to process. /// /// The current instance of the class. /// @@ -533,7 +533,7 @@ namespace ImageProcessor /// /// Uses the - /// to fix the colour palette of gif images. + /// to fix the color palette of gif images. /// private void FixGifs() { diff --git a/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs index 6fdd1f11d..bea19b178 100644 --- a/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/BlackWhiteMatrixFilter.cs @@ -19,10 +19,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a black and white filter to an image. /// - class BlackWhiteMatrixFilter : IMatrixFilter + internal class BlackWhiteMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs index 93394037e..ce694a4b3 100644 --- a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs @@ -17,7 +17,7 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a comic filter to an image. /// - class ComicMatrixFilter : IMatrixFilter + internal class ComicMatrixFilter : IMatrixFilter { /// /// Enumurates Argb colour channels. diff --git a/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs index 3f679d130..327789852 100644 --- a/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/GothamMatrixFilter.cs @@ -20,10 +20,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a gotham filter to an image. /// - class GothamMatrixFilter : IMatrixFilter + internal class GothamMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs index 46b64a379..fa3874e51 100644 --- a/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/GreyScaleMatrixFilter.cs @@ -19,10 +19,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a greyscale filter to an image. /// - class GreyScaleMatrixFilter : IMatrixFilter + internal class GreyScaleMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs index 1e6946f60..47bff6d76 100644 --- a/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/HiSatchMatrixFilter.cs @@ -19,10 +19,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a high saturated filter to an image. /// - class HiSatchMatrixFilter : IMatrixFilter + internal class HiSatchMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs index 89783de41..4de697fb3 100644 --- a/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/IMatrixFilter.cs @@ -18,7 +18,7 @@ namespace ImageProcessor.Imaging.Filters interface IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// ColorMatrix Matrix { get; } diff --git a/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs index dfd40b65f..71bc16996 100644 --- a/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/InvertMatrixFilter.cs @@ -19,10 +19,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add an inverted filter to an image. /// - class InvertMatrixFilter : IMatrixFilter + internal class InvertMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs index b02d19ad0..db7d97266 100644 --- a/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/LoSatchMatrixFilter.cs @@ -19,10 +19,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a low saturated filter to an image. /// - class LoSatchMatrixFilter : IMatrixFilter + internal class LoSatchMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs index d9b92158f..e69e2066c 100644 --- a/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/LomographMatrixFilter.cs @@ -20,10 +20,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a lomograph filter to an image. /// - class LomographMatrixFilter : IMatrixFilter + internal class LomographMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs index 60cd46ef7..618209c9d 100644 --- a/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/PolaroidMatrixFilter.cs @@ -21,10 +21,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a polaroid filter to an image. /// - class PolaroidMatrixFilter : IMatrixFilter + internal class PolaroidMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs index 6277a76a7..1dc057974 100644 --- a/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/SepiaMatrixFilter.cs @@ -19,10 +19,10 @@ namespace ImageProcessor.Imaging.Filters /// /// Encapsulates methods with which to add a sepia filter to an image. /// - class SepiaMatrixFilter : IMatrixFilter + internal class SepiaMatrixFilter : IMatrixFilter { /// - /// Gets the for this filter instance. + /// Gets the for this filter instance. /// public ColorMatrix Matrix { diff --git a/src/ImageProcessor/Imaging/RotateLayer.cs b/src/ImageProcessor/Imaging/RotateLayer.cs index ad4790714..a56fa54c9 100644 --- a/src/ImageProcessor/Imaging/RotateLayer.cs +++ b/src/ImageProcessor/Imaging/RotateLayer.cs @@ -8,13 +8,15 @@ namespace ImageProcessor.Imaging { #region Using + using System; + using System.Collections.Generic; using System.Drawing; #endregion /// - /// Enacapsulates the properties required to rotate an image. + /// Encapsulates the properties required to rotate an image. /// - public class RotateLayer + public class RotateLayer : IEqualityComparer { #region Constructors /// @@ -37,5 +39,58 @@ namespace ImageProcessor.Imaging /// public Color BackgroundColor { get; set; } #endregion + + /// + /// Returns a value indicating whether this instance is equal to another . + /// + /// + /// The other to compare to. + /// + /// + /// True if this instance is equal to another ; otherwise, false. + /// + public bool Equals(RotateLayer other) + { + return this.Angle.Equals(other.Angle) && this.BackgroundColor.Equals(other.BackgroundColor); + } + + /// + /// Determines whether the specified objects are equal. + /// + /// + /// true if the specified objects are equal; otherwise, false. + /// + /// + /// The first object of type to compare. + /// + /// + /// The second object of type to compare. + /// + public bool Equals(RotateLayer x, RotateLayer y) + { + return x.Angle.Equals(y.Angle) && x.BackgroundColor.Equals(y.BackgroundColor); + } + + /// + /// Returns a hash code for the specified object. + /// + /// + /// A hash code for the specified object. + /// + /// + /// The for which a hash code is to be returned. + /// + /// + /// The type of is a reference type and is null. + /// + public int GetHashCode(RotateLayer obj) + { + if (obj == null) + { + throw new ArgumentNullException(); + } + + return this.Angle.GetHashCode() + this.BackgroundColor.GetHashCode(); + } } } diff --git a/src/ImageProcessor/Processors/Copy of Filter.cs b/src/ImageProcessor/Processors/Copy of Filter.cs deleted file mode 100644 index df31ffce8..000000000 --- a/src/ImageProcessor/Processors/Copy of Filter.cs +++ /dev/null @@ -1,610 +0,0 @@ -// ----------------------------------------------------------------------- -// -// TODO: Update copyright text. -// -// ----------------------------------------------------------------------- - -namespace ImageProcessor.Processors -{ - #region Using - - using System; - using System.Collections.Generic; - using System.Drawing; - using System.Drawing.Drawing2D; - using System.Drawing.Imaging; - using System.IO; - using System.Text.RegularExpressions; - using System.Web; - using System.Web.Hosting; - - #endregion - - /// - /// Encapsulates methods with which to add filters to an image. - /// - public class Filter : IGraphicsProcessor - { - /// - /// The regular expression to search strings for. - /// - private static readonly Regex QueryRegex = new Regex(@"filter=(lomograph|polaroid|blackwhite|sepia|greyscale|gotham|invert|hisatch|losatch|comic)", RegexOptions.Compiled); - - /// - /// Enumurates Argb colour channels. - /// - private enum ChannelArgb - { - /// - /// The blue channel - /// - Blue = 0, - - /// - /// The green channel - /// - Green = 1, - - /// - /// The red channel - /// - Red = 2, - - /// - /// The alpha channel - /// - Alpha = 3 - } - - #region IGraphicsProcessor Members - /// - /// Gets the name. - /// - public string Name - { - get - { - return "Filter"; - } - } - - /// - /// Gets the description. - /// - public string Description - { - get - { - return "Encapsulates methods with which to add filters to an image. e.g polaroid, lomograph"; - } - } - - /// - /// Gets the regular expression to search strings for. - /// - public Regex RegexPattern - { - get - { - return QueryRegex; - } - } - - /// - /// Gets or sets DynamicParameter. - /// - public dynamic DynamicParameter - { - get; - set; - } - - /// - /// Gets the order in which this processor is to be used in a chain. - /// - public int SortOrder - { - get; - private set; - } - - /// - /// Gets or sets any additional settings required by the processor. - /// - public Dictionary Settings - { - get; - set; - } - - /// - /// The position in the original string where the first character of the captured substring was found. - /// - /// - /// The query string to search. - /// - /// - /// The zero-based starting position in the original string where the captured substring was found. - /// - 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; - this.DynamicParameter = match.Value.Split('=')[1]; - } - - index += 1; - } - } - - return this.SortOrder; - } - - /// - /// Processes the image. - /// - /// - /// The 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) - { - Bitmap newImage = null; - Image image = factory.Image; - - // Bitmaps for comic pattern - Bitmap hisatchBitmap = null; - Bitmap patternBitmap = null; - - try - { - // Dont use an object initializer here. - newImage = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppPArgb); - newImage.Tag = image.Tag; - - ColorMatrix colorMatrix = null; - - switch ((string)this.DynamicParameter) - { - case "polaroid": - colorMatrix = ColorMatrixes.Polaroid; - break; - case "lomograph": - colorMatrix = ColorMatrixes.Lomograph; - break; - case "sepia": - colorMatrix = ColorMatrixes.Sepia; - break; - case "blackwhite": - colorMatrix = ColorMatrixes.BlackWhite; - break; - case "greyscale": - colorMatrix = ColorMatrixes.GreyScale; - break; - case "gotham": - colorMatrix = ColorMatrixes.Gotham; - break; - case "invert": - colorMatrix = ColorMatrixes.Invert; - break; - case "hisatch": - colorMatrix = ColorMatrixes.HiSatch; - break; - case "losatch": - colorMatrix = ColorMatrixes.LoSatch; - break; - case "comic": - colorMatrix = ColorMatrixes.LoSatch; - break; - } - - using (Graphics graphics = Graphics.FromImage(newImage)) - { - using (ImageAttributes attributes = new ImageAttributes()) - { - if (colorMatrix != null) - { - attributes.SetColorMatrix(colorMatrix); - } - - Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height); - - if (this.DynamicParameter == "comic") - { - // Set the attributes to LoSatch and draw the image. - graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); - - // Create a bitmap for overlaying. - hisatchBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); - - // Set the color matrix - attributes.SetColorMatrix(ColorMatrixes.HiSatch); - - // Draw the image with the hisatch colormatrix. - using (var g = Graphics.FromImage(hisatchBitmap)) - { - g.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); - } - - // We need to create a new image now with the hi saturation colormatrix and a pattern mask to paint it - // onto the other image with. - patternBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); - - // Create the pattern mask. - using (var g = Graphics.FromImage(patternBitmap)) - { - g.Clear(Color.Black); - g.SmoothingMode = SmoothingMode.HighQuality; - for (var y = 0; y < image.Height; y += 10) - { - for (var x = 0; x < image.Width; x += 6) - { - g.FillEllipse(Brushes.White, x, y, 4, 4); - g.FillEllipse(Brushes.White, x + 3, y + 5, 4, 4); - } - } - } - - // Transfer the alpha channel from the mask to the hi sturation image. - TransferOneArgbChannelFromOneBitmapToAnother(patternBitmap, hisatchBitmap, ChannelArgb.Blue, ChannelArgb.Alpha); - - // Overlay the image. - graphics.DrawImage(hisatchBitmap, 0, 0); - - // Dispose of the other images - hisatchBitmap.Dispose(); - patternBitmap.Dispose(); - } - else - { - graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); - - // Polaroid requires an extra tweak. - if (this.DynamicParameter == "polaroid") - { - using (GraphicsPath path = new GraphicsPath()) - { - path.AddEllipse(rectangle); - using (PathGradientBrush brush = new PathGradientBrush(path)) - { - // Fill a rectangle with an elliptical gradient brush that goes from orange to transparent. - // This has the effect of painting the far corners transparent and fading in to orange on the - // way in to the centre. - brush.WrapMode = WrapMode.Tile; - brush.CenterColor = Color.FromArgb(70, 255, 153, 102); - brush.SurroundColors = new Color[] { Color.FromArgb(0, 0, 0, 0) }; - - Blend blend = new Blend - { - Positions = new float[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F }, - Factors = new float[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f } - }; - - brush.Blend = blend; - - Region oldClip = graphics.Clip; - graphics.Clip = new Region(rectangle); - graphics.FillRectangle(brush, rectangle); - graphics.Clip = oldClip; - } - } - } - - // Gotham requires an extra tweak. - if (this.DynamicParameter == "gotham") - { - using (GraphicsPath path = new GraphicsPath()) - { - path.AddRectangle(rectangle); - - // Paint a burgundy rectangle with a transparency of ~30% over the image. - // Paint a blue rectangle with a transparency of 20% over the image. - using (SolidBrush brush = new SolidBrush(Color.FromArgb(77, 43, 4, 18))) - { - Region oldClip = graphics.Clip; - graphics.Clip = new Region(rectangle); - graphics.FillRectangle(brush, rectangle); - - // Fill the blue. - brush.Color = Color.FromArgb(51, 12, 22, 88); - graphics.FillRectangle(brush, rectangle); - graphics.Clip = oldClip; - } - } - } - } - } - } - - // Add a vignette to finish the effect. - // TODO: This feels a bit mucky so I might chop it out. - if (this.DynamicParameter == "polaroid" || this.DynamicParameter == "lomograph") - { - factory.Image = newImage; - Vignette vignette = new Vignette(); - newImage = (Bitmap)vignette.ProcessImage(factory); - } - - // Reassign the image. - image.Dispose(); - image = newImage; - } - catch - { - if (newImage != null) - { - newImage.Dispose(); - } - - if (hisatchBitmap != null) - { - hisatchBitmap.Dispose(); - } - - if (patternBitmap != null) - { - patternBitmap.Dispose(); - } - } - - return image; - } - #endregion - - /// - /// Transfers a single ARGB channel from one image to another. - /// - /// - /// The source. - /// - /// - /// The destination. - /// - /// - /// The source channel. - /// - /// - /// The destination channel. - /// - private static void TransferOneArgbChannelFromOneBitmapToAnother(Bitmap source, Bitmap destination, ChannelArgb sourceChannel, ChannelArgb destinationChannel) - { - if (source.Size != destination.Size) - { - throw new ArgumentException(); - } - - Rectangle rectangle = new Rectangle(Point.Empty, source.Size); - - // Lockbits the source. - BitmapData bitmapDataSource = source.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); - - // Declare an array to hold the bytes of the bitmap. - int bytes = bitmapDataSource.Stride * bitmapDataSource.Height; - - // Allocate a buffer for the source image - byte[] sourceRgbValues = new byte[bytes]; - - // Copy the RGB values into the array. - System.Runtime.InteropServices.Marshal.Copy(bitmapDataSource.Scan0, sourceRgbValues, 0, bytes); - - // Unlockbits the source. - source.UnlockBits(bitmapDataSource); - - // Lockbits the destination. - BitmapData bitmapDataDestination = destination.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); - - // Allocate a buffer for image - byte[] destinationRgbValues = new byte[bytes]; - - // Copy the RGB values into the array. - System.Runtime.InteropServices.Marshal.Copy(bitmapDataDestination.Scan0, destinationRgbValues, 0, bytes); - - int s = (int)sourceChannel; - int d = (int)destinationChannel; - - for (int i = rectangle.Height * rectangle.Width; i > 0; i--) - { - destinationRgbValues[d] = sourceRgbValues[s]; - d += 4; - s += 4; - } - - // Copy the RGB values back to the bitmap - System.Runtime.InteropServices.Marshal.Copy(destinationRgbValues, 0, bitmapDataDestination.Scan0, bytes); - - // Unlock bits the destination. - destination.UnlockBits(bitmapDataDestination); - } - - /// - /// A list of available color matrices to apply to an image. - /// - private static class ColorMatrixes - { - /// - /// Gets Sepia. - /// - internal static ColorMatrix Sepia - { - get - { - return new ColorMatrix( - new float[][] - { - new float[] { .393f, .349f, .272f, 0, 0 }, - new float[] { .769f, .686f, .534f, 0, 0 }, - new float[] { .189f, .168f, .131f, 0, 0 }, - new float[] { 0, 0, 0, 1, 0 }, - new float[] { 0, 0, 0, 0, 1 } - }); - } - } - - /// - /// Gets BlackWhite. - /// - internal static ColorMatrix BlackWhite - { - get - { - return new ColorMatrix( - new float[][] - { - 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 float[] { 0, 0, 0, 1, 0 }, - new float[] { -1, -1, -1, 0, 1 } - }); - } - } - - /// - /// Gets Polaroid. - /// - internal static ColorMatrix Polaroid - { - get - { - return new ColorMatrix( - new float[][] - { - 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 float[] { 0, 0, 0, 1, 0 }, - new float[] { 0.06f, -0.05f, -0.05f, 0, 1 } - }); - } - } - - /// - /// Gets Lomograph. - /// - internal static ColorMatrix Lomograph - { - get - { - return new ColorMatrix( - new float[][] - { - 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 float[] { 0, 0, 0, 1, 0 }, - new float[] { -0.10f, 0.05f, -0.08f, 0, 1 } - }); - } - } - - /// - /// Gets GreyScale. - /// - internal static ColorMatrix GreyScale - { - get - { - return new ColorMatrix( - new float[][] - { - new float[] { .33f, .33f, .33f, 0, 0 }, - new float[] { .59f, .59f, .59f, 0, 0 }, - new float[] { .11f, .11f, .11f, 0, 0 }, - new float[] { 0, 0, 0, 1, 0 }, - new float[] { 0, 0, 0, 0, 1 } - }); - } - } - - /// - /// Gets Gotham. - /// - internal static ColorMatrix Gotham - { - get - { - return new ColorMatrix( - new float[][] - { - new float[] { .9f, .9f, .9f, 0, 0 }, - new float[] { .9f, .9f, .9f, 0, 0 }, - new float[] { .9f, .9f, .9f, 0, 0 }, - new float[] { 0, 0, 0, 1, 0 }, - new float[] { -.5f, -.5f, -.45f, 0, 1 } - }); - } - } - - /// - /// Gets Invert. - /// - internal static ColorMatrix Invert - { - get - { - return new ColorMatrix( - new float[][] - { - 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[] { 1, 1, 1, 0, 1 } - }); - } - } - - /// - /// Gets HiSatch. - /// - internal static ColorMatrix HiSatch - { - get - { - return new ColorMatrix( - new float[][] - { - new float[] { 3, -1, -1, 0, 0 }, - new float[] { -1, 3, -1, 0, 0 }, - new float[] { -1, -1, 3, 0, 0 }, - new float[] { 0, 0, 0, 1, 0 }, - new float[] { 0, 0, 0, 0, 1 } - }); - } - } - - /// - /// Gets LoSatch. - /// - internal static ColorMatrix LoSatch - { - get - { - return new ColorMatrix( - new float[][] - { - 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 } - }); - } - } - } - } -} diff --git a/src/ImageProcessor/Processors/Png8.cs b/src/ImageProcessor/Processors/Png8.cs deleted file mode 100644 index 36b44f0b7..000000000 --- a/src/ImageProcessor/Processors/Png8.cs +++ /dev/null @@ -1,147 +0,0 @@ -// ----------------------------------------------------------------------- -// -// TODO: Update copyright text. -// -// ----------------------------------------------------------------------- - -namespace ImageProcessor.Processors -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Drawing; - using System.Linq; - using System.Text; - using System.Text.RegularExpressions; - using ImageProcessor.Imaging; - - /// - /// TODO: Update summary. - /// - public class Png8 : IGraphicsProcessor - { - #region Implementation of IGraphicsProcessor - - /// - /// Gets the name. - /// - public string Name - { - get - { - throw new NotImplementedException(); - } - } - - /// - /// Gets the description. - /// - public string Description - { - get - { - throw new NotImplementedException(); - } - } - - /// - /// Gets the regular expression to search strings for. - /// - public Regex RegexPattern - { - get - { - throw new NotImplementedException(); - } - } - - /// - /// Gets DynamicParameter. - /// - public dynamic DynamicParameter - { - get - { - throw new NotImplementedException(); - } - } - - /// - /// Gets the order in which this processor is to be used in a chain. - /// - public int SortOrder - { - get - { - throw new NotImplementedException(); - } - } - - /// - /// Gets or sets any additional settings required by the processor. - /// - public Dictionary Settings - { - get - { - throw new NotImplementedException(); - } - set - { - throw new NotImplementedException(); - } - } - - /// - /// The position in the original string where the first character of the captured substring was found. - /// - /// - /// The query string to search. - /// - /// - /// The zero-based starting position in the original string where the captured substring was found. - /// - public int MatchRegexIndex(string queryString) - { - throw new NotImplementedException(); - } - - /// - /// Processes the image. - /// - /// - /// The 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) - { - Bitmap newImage = null; - Image image = factory.Image; - try - { - newImage = new Bitmap(image) { Tag = image.Tag }; - using (Graphics graphics = Graphics.FromImage(newImage)) - { - ArrayList pallete = new ArrayList(); - PaletteQuantizer paletteQuantizer = new PaletteQuantizer(new ArrayList(newImage.Palette.Entries)); - newImage = paletteQuantizer.Quantize(newImage); - } - - } - catch - { - if (newImage != null) - { - newImage.Dispose(); - } - } - - return image; - } - - #endregion - } -} diff --git a/src/ImageProcessor/Properties/AssemblyInfo.cs b/src/ImageProcessor/Properties/AssemblyInfo.cs index 23e407cbc..87a64030b 100644 --- a/src/ImageProcessor/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor/Properties/AssemblyInfo.cs @@ -32,6 +32,6 @@ using System.Security; // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.3.0.0")] -[assembly: AssemblyFileVersion("1.3.0.0")] +[assembly: AssemblyVersion("1.4.0.0")] +[assembly: AssemblyFileVersion("1.4.0.0")] diff --git a/src/Nuget/ImageProcessor.1.4.0.0.nupkg b/src/Nuget/ImageProcessor.1.4.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..e3dfdce912a7cd880e9d4e639c66b1a58bf27114 GIT binary patch literal 26030 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 z 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 bWA&noKG1gxWQSQ + +